This is an automated email from the ASF dual-hosted git repository.

zjffdu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a238f4  [ZEPPELIN-4019] Interpreter process get note from server
0a238f4 is described below

commit 0a238f4cbcf73e9f3806feeb7573e94937046f3b
Author: liuxunorg <33611...@qq.com>
AuthorDate: Tue Mar 5 11:25:29 2019 +0800

    [ZEPPELIN-4019] Interpreter process get note from server
    
    ### What is this PR for?
    The interpreter is executed according to the paragraph. Click the run 
button in the paragraph, and only the code content in the current paragraph can 
be obtained in the interpreter process.
    
    To pass the Dashboard paragraph in the submarine interpreter, you need to 
submit all the code content in this note to tensorflow for execution.
    
    So, I think need to get the note data in sever through 
`RemoteInterpreterEventServer` in the interpreter process.
    
    I implemented two other methods, so that the interpreter can get the note 
in the server, the actual running effect is not the best solution.
    
    **1) By having the interpreter directly access the external storage of the 
note repository, such as HDFS, S3.**
    
    1. But this limits the need to store notes in an external storage system.
    2. In hdfs with kerberos authentication system enabled, not all users can 
access the note folder.
    
    **2) Get the note from the server from the REST client in the interpreter.**
    
    1. Need to let zeppelin/api/notes intercept in shrio.ini.
    2. Or let the interpreter access the REST interface of the server through 
the user and password, but it is not safe.
    
    In addition, in 
[JIRA-4018](https://issues.apache.org/jira/browse/ZEPPELIN-4018) Workflow and 
orchestration, it is also necessary to query all the notes and paragraphs of 
the user in the workflow paragraph for the execution of the note.
    
    ### What type of PR is it?
    [Improvement]
    
    ### Todos
    * [ ] - Task
    
    ### What is the Jira issue?
    * https://issues.apache.org/jira/browse/ZEPPELIN-4019
    
    ### How should this be tested?
    ShellInterpreter::internalInterpret(String cmd, InterpreterContext 
contextInterpreter)
    ```
    String noteJson = contextInterpreter.getIntpEventClient().getNoteFromServer(
        cmd,
        contextInterpreter.getAuthenticationInfo(), true);
    if (null != noteJson) {
      LOGGER.info(noteJson);
      return new InterpreterResult(Code.SUCCESS, noteJson);
    }
    
    return new InterpreterResult(Code.ERROR, "can not get note :" + cmd);
    ```
    
    ### Screenshots (if appropriate)
    
![getnotefromserver](https://user-images.githubusercontent.com/3677382/53401050-088b7b00-39ea-11e9-9f12-caee4d194fac.gif)
    
    [CI pass](https://travis-ci.org/liuxunorg/zeppelin/builds/498581356)
    
    * Does the licenses files need update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    Author: liuxunorg <33611...@qq.com>
    
    Closes #3314 from liuxunorg/ZEPPELIN-4019 and squashes the following 
commits:
    
    2cb917c12 [liuxunorg] Optimization code.
    c2c321fa6 [liuxunorg] Catch ServiceException in NotebookServerTest.
    3a62d74ae [liuxunorg] Add NotebookServerTest throws TException.
    60a3bd9a2 [liuxunorg] Add the display of exception information `without 
permissions` and `no exist this note`.
    732cfc22c [liuxunorg] modify `getNoteFromServer()` to `getParagraphList()`.
    763435d76 [liuxunorg] [ZEPPELIN-4019] Interpreter process get the note from 
zeppelin server
---
 .../remote/RemoteInterpreterEventClient.java       |    9 +
 .../interpreter/thrift/AngularObjectId.java        |    2 +-
 .../interpreter/thrift/AppOutputAppendEvent.java   |    2 +-
 .../interpreter/thrift/AppOutputUpdateEvent.java   |    2 +-
 .../interpreter/thrift/AppStatusUpdateEvent.java   |    2 +-
 .../interpreter/thrift/InterpreterCompletion.java  |    2 +-
 .../interpreter/thrift/OutputAppendEvent.java      |    2 +-
 .../interpreter/thrift/OutputUpdateAllEvent.java   |    2 +-
 .../interpreter/thrift/OutputUpdateEvent.java      |    2 +-
 ...ppStatusUpdateEvent.java => ParagraphInfo.java} |  280 ++---
 .../zeppelin/interpreter/thrift/RegisterInfo.java  |    2 +-
 .../thrift/RemoteApplicationResult.java            |    2 +-
 .../thrift/RemoteInterpreterContext.java           |    2 +-
 .../interpreter/thrift/RemoteInterpreterEvent.java |    2 +-
 .../thrift/RemoteInterpreterEventService.java      | 1139 +++++++++++++++++++-
 .../thrift/RemoteInterpreterResult.java            |    2 +-
 .../thrift/RemoteInterpreterResultMessage.java     |    2 +-
 .../thrift/RemoteInterpreterService.java           |    2 +-
 .../interpreter/thrift/RunParagraphsEvent.java     |    2 +-
 ...terResultMessage.java => ServiceException.java} |  280 ++---
 .../thrift/RemoteInterpreterEventService.thrift    |   13 +
 .../org/apache/zeppelin/socket/NotebookServer.java |   41 +
 .../apache/zeppelin/socket/NotebookServerTest.java |   68 ++
 .../interpreter/RemoteInterpreterEventServer.java  |   20 +-
 .../remote/RemoteInterpreterProcessListener.java   |    6 +
 .../remote/RemoteInterpreterOutputTestStream.java  |    7 +
 .../zeppelin/scheduler/RemoteSchedulerTest.java    |    7 +
 27 files changed, 1547 insertions(+), 355 deletions(-)

diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
index 287095d..b7e77c6 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
@@ -28,13 +28,16 @@ import 
org.apache.zeppelin.interpreter.thrift.AppStatusUpdateEvent;
 import org.apache.zeppelin.interpreter.thrift.OutputAppendEvent;
 import org.apache.zeppelin.interpreter.thrift.OutputUpdateAllEvent;
 import org.apache.zeppelin.interpreter.thrift.OutputUpdateEvent;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEventService;
 import org.apache.zeppelin.interpreter.thrift.RunParagraphsEvent;
+import org.apache.zeppelin.interpreter.thrift.ServiceException;
 import org.apache.zeppelin.resource.RemoteResource;
 import org.apache.zeppelin.resource.Resource;
 import org.apache.zeppelin.resource.ResourceId;
 import org.apache.zeppelin.resource.ResourcePoolConnector;
 import org.apache.zeppelin.resource.ResourceSet;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,6 +89,12 @@ public class RemoteInterpreterEventClient implements 
ResourcePoolConnector,
     }
   }
 
+  public synchronized List<ParagraphInfo> getParagraphList(String user, String 
noteId)
+      throws TException, ServiceException {
+    List<ParagraphInfo> paragraphList = 
intpEventServiceClient.getParagraphList(user, noteId);
+    return paragraphList;
+  }
+
   @Override
   public synchronized Object readResource(ResourceId resourceId) {
     try {
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AngularObjectId.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AngularObjectId.java
index b659d94..24e9fd9 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AngularObjectId.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AngularObjectId.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class AngularObjectId implements 
org.apache.thrift.TBase<AngularObjectId, AngularObjectId._Fields>, 
java.io.Serializable, Cloneable, Comparable<AngularObjectId> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("AngularObjectId");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputAppendEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputAppendEvent.java
index c0ec91f..bac58e9 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputAppendEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputAppendEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class AppOutputAppendEvent implements 
org.apache.thrift.TBase<AppOutputAppendEvent, AppOutputAppendEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<AppOutputAppendEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("AppOutputAppendEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputUpdateEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputUpdateEvent.java
index a37f828..03ff738 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputUpdateEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppOutputUpdateEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class AppOutputUpdateEvent implements 
org.apache.thrift.TBase<AppOutputUpdateEvent, AppOutputUpdateEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<AppOutputUpdateEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("AppOutputUpdateEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
index 5923dcc..ad09d5d 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUpdateEvent, AppStatusUpdateEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<AppStatusUpdateEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("AppStatusUpdateEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
index 68caf43..d19d1ac 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class InterpreterCompletion implements 
org.apache.thrift.TBase<InterpreterCompletion, InterpreterCompletion._Fields>, 
java.io.Serializable, Cloneable, Comparable<InterpreterCompletion> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("InterpreterCompletion");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputAppendEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputAppendEvent.java
index ec175e0..69abc08 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputAppendEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputAppendEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class OutputAppendEvent implements 
org.apache.thrift.TBase<OutputAppendEvent, OutputAppendEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<OutputAppendEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("OutputAppendEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateAllEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateAllEvent.java
index 9ee8858..ac32e6e 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateAllEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateAllEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class OutputUpdateAllEvent implements 
org.apache.thrift.TBase<OutputUpdateAllEvent, OutputUpdateAllEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<OutputUpdateAllEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("OutputUpdateAllEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateEvent.java
index 1cf328c..0e226ba 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/OutputUpdateEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class OutputUpdateEvent implements 
org.apache.thrift.TBase<OutputUpdateEvent, OutputUpdateEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<OutputUpdateEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("OutputUpdateEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ParagraphInfo.java
similarity index 69%
copy from 
zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
copy to 
zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ParagraphInfo.java
index 5923dcc..bd50d99 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/AppStatusUpdateEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ParagraphInfo.java
@@ -51,32 +51,32 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
-public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUpdateEvent, AppStatusUpdateEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<AppStatusUpdateEvent> {
-  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("AppStatusUpdateEvent");
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
+public class ParagraphInfo implements org.apache.thrift.TBase<ParagraphInfo, 
ParagraphInfo._Fields>, java.io.Serializable, Cloneable, 
Comparable<ParagraphInfo> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("ParagraphInfo");
 
   private static final org.apache.thrift.protocol.TField NOTE_ID_FIELD_DESC = 
new org.apache.thrift.protocol.TField("noteId", 
org.apache.thrift.protocol.TType.STRING, (short)1);
   private static final org.apache.thrift.protocol.TField 
PARAGRAPH_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("paragraphId", 
org.apache.thrift.protocol.TType.STRING, (short)2);
-  private static final org.apache.thrift.protocol.TField APP_ID_FIELD_DESC = 
new org.apache.thrift.protocol.TField("appId", 
org.apache.thrift.protocol.TType.STRING, (short)3);
-  private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = 
new org.apache.thrift.protocol.TField("status", 
org.apache.thrift.protocol.TType.STRING, (short)4);
+  private static final org.apache.thrift.protocol.TField 
PARAGRAPH_TITLE_FIELD_DESC = new 
org.apache.thrift.protocol.TField("paragraphTitle", 
org.apache.thrift.protocol.TType.STRING, (short)3);
+  private static final org.apache.thrift.protocol.TField 
PARAGRAPH_TEXT_FIELD_DESC = new 
org.apache.thrift.protocol.TField("paragraphText", 
org.apache.thrift.protocol.TType.STRING, (short)4);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = 
new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
-    schemes.put(StandardScheme.class, new 
AppStatusUpdateEventStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new 
AppStatusUpdateEventTupleSchemeFactory());
+    schemes.put(StandardScheme.class, new 
ParagraphInfoStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new ParagraphInfoTupleSchemeFactory());
   }
 
   public String noteId; // required
   public String paragraphId; // required
-  public String appId; // required
-  public String status; // required
+  public String paragraphTitle; // required
+  public String paragraphText; // required
 
   /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
     NOTE_ID((short)1, "noteId"),
     PARAGRAPH_ID((short)2, "paragraphId"),
-    APP_ID((short)3, "appId"),
-    STATUS((short)4, "status");
+    PARAGRAPH_TITLE((short)3, "paragraphTitle"),
+    PARAGRAPH_TEXT((short)4, "paragraphText");
 
     private static final Map<String, _Fields> byName = new HashMap<String, 
_Fields>();
 
@@ -95,10 +95,10 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
           return NOTE_ID;
         case 2: // PARAGRAPH_ID
           return PARAGRAPH_ID;
-        case 3: // APP_ID
-          return APP_ID;
-        case 4: // STATUS
-          return STATUS;
+        case 3: // PARAGRAPH_TITLE
+          return PARAGRAPH_TITLE;
+        case 4: // PARAGRAPH_TEXT
+          return PARAGRAPH_TEXT;
         default:
           return null;
       }
@@ -146,65 +146,65 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.PARAGRAPH_ID, new 
org.apache.thrift.meta_data.FieldMetaData("paragraphId", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-    tmpMap.put(_Fields.APP_ID, new 
org.apache.thrift.meta_data.FieldMetaData("appId", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+    tmpMap.put(_Fields.PARAGRAPH_TITLE, new 
org.apache.thrift.meta_data.FieldMetaData("paragraphTitle", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-    tmpMap.put(_Fields.STATUS, new 
org.apache.thrift.meta_data.FieldMetaData("status", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+    tmpMap.put(_Fields.PARAGRAPH_TEXT, new 
org.apache.thrift.meta_data.FieldMetaData("paragraphText", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     metaDataMap = Collections.unmodifiableMap(tmpMap);
-    
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(AppStatusUpdateEvent.class,
 metaDataMap);
+    
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ParagraphInfo.class,
 metaDataMap);
   }
 
-  public AppStatusUpdateEvent() {
+  public ParagraphInfo() {
   }
 
-  public AppStatusUpdateEvent(
+  public ParagraphInfo(
     String noteId,
     String paragraphId,
-    String appId,
-    String status)
+    String paragraphTitle,
+    String paragraphText)
   {
     this();
     this.noteId = noteId;
     this.paragraphId = paragraphId;
-    this.appId = appId;
-    this.status = status;
+    this.paragraphTitle = paragraphTitle;
+    this.paragraphText = paragraphText;
   }
 
   /**
    * Performs a deep copy on <i>other</i>.
    */
-  public AppStatusUpdateEvent(AppStatusUpdateEvent other) {
+  public ParagraphInfo(ParagraphInfo other) {
     if (other.isSetNoteId()) {
       this.noteId = other.noteId;
     }
     if (other.isSetParagraphId()) {
       this.paragraphId = other.paragraphId;
     }
-    if (other.isSetAppId()) {
-      this.appId = other.appId;
+    if (other.isSetParagraphTitle()) {
+      this.paragraphTitle = other.paragraphTitle;
     }
-    if (other.isSetStatus()) {
-      this.status = other.status;
+    if (other.isSetParagraphText()) {
+      this.paragraphText = other.paragraphText;
     }
   }
 
-  public AppStatusUpdateEvent deepCopy() {
-    return new AppStatusUpdateEvent(this);
+  public ParagraphInfo deepCopy() {
+    return new ParagraphInfo(this);
   }
 
   @Override
   public void clear() {
     this.noteId = null;
     this.paragraphId = null;
-    this.appId = null;
-    this.status = null;
+    this.paragraphTitle = null;
+    this.paragraphText = null;
   }
 
   public String getNoteId() {
     return this.noteId;
   }
 
-  public AppStatusUpdateEvent setNoteId(String noteId) {
+  public ParagraphInfo setNoteId(String noteId) {
     this.noteId = noteId;
     return this;
   }
@@ -228,7 +228,7 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     return this.paragraphId;
   }
 
-  public AppStatusUpdateEvent setParagraphId(String paragraphId) {
+  public ParagraphInfo setParagraphId(String paragraphId) {
     this.paragraphId = paragraphId;
     return this;
   }
@@ -248,51 +248,51 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     }
   }
 
-  public String getAppId() {
-    return this.appId;
+  public String getParagraphTitle() {
+    return this.paragraphTitle;
   }
 
-  public AppStatusUpdateEvent setAppId(String appId) {
-    this.appId = appId;
+  public ParagraphInfo setParagraphTitle(String paragraphTitle) {
+    this.paragraphTitle = paragraphTitle;
     return this;
   }
 
-  public void unsetAppId() {
-    this.appId = null;
+  public void unsetParagraphTitle() {
+    this.paragraphTitle = null;
   }
 
-  /** Returns true if field appId is set (has been assigned a value) and false 
otherwise */
-  public boolean isSetAppId() {
-    return this.appId != null;
+  /** Returns true if field paragraphTitle is set (has been assigned a value) 
and false otherwise */
+  public boolean isSetParagraphTitle() {
+    return this.paragraphTitle != null;
   }
 
-  public void setAppIdIsSet(boolean value) {
+  public void setParagraphTitleIsSet(boolean value) {
     if (!value) {
-      this.appId = null;
+      this.paragraphTitle = null;
     }
   }
 
-  public String getStatus() {
-    return this.status;
+  public String getParagraphText() {
+    return this.paragraphText;
   }
 
-  public AppStatusUpdateEvent setStatus(String status) {
-    this.status = status;
+  public ParagraphInfo setParagraphText(String paragraphText) {
+    this.paragraphText = paragraphText;
     return this;
   }
 
-  public void unsetStatus() {
-    this.status = null;
+  public void unsetParagraphText() {
+    this.paragraphText = null;
   }
 
-  /** Returns true if field status is set (has been assigned a value) and 
false otherwise */
-  public boolean isSetStatus() {
-    return this.status != null;
+  /** Returns true if field paragraphText is set (has been assigned a value) 
and false otherwise */
+  public boolean isSetParagraphText() {
+    return this.paragraphText != null;
   }
 
-  public void setStatusIsSet(boolean value) {
+  public void setParagraphTextIsSet(boolean value) {
     if (!value) {
-      this.status = null;
+      this.paragraphText = null;
     }
   }
 
@@ -314,19 +314,19 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
       }
       break;
 
-    case APP_ID:
+    case PARAGRAPH_TITLE:
       if (value == null) {
-        unsetAppId();
+        unsetParagraphTitle();
       } else {
-        setAppId((String)value);
+        setParagraphTitle((String)value);
       }
       break;
 
-    case STATUS:
+    case PARAGRAPH_TEXT:
       if (value == null) {
-        unsetStatus();
+        unsetParagraphText();
       } else {
-        setStatus((String)value);
+        setParagraphText((String)value);
       }
       break;
 
@@ -341,11 +341,11 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     case PARAGRAPH_ID:
       return getParagraphId();
 
-    case APP_ID:
-      return getAppId();
+    case PARAGRAPH_TITLE:
+      return getParagraphTitle();
 
-    case STATUS:
-      return getStatus();
+    case PARAGRAPH_TEXT:
+      return getParagraphText();
 
     }
     throw new IllegalStateException();
@@ -362,10 +362,10 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
       return isSetNoteId();
     case PARAGRAPH_ID:
       return isSetParagraphId();
-    case APP_ID:
-      return isSetAppId();
-    case STATUS:
-      return isSetStatus();
+    case PARAGRAPH_TITLE:
+      return isSetParagraphTitle();
+    case PARAGRAPH_TEXT:
+      return isSetParagraphText();
     }
     throw new IllegalStateException();
   }
@@ -374,12 +374,12 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
   public boolean equals(Object that) {
     if (that == null)
       return false;
-    if (that instanceof AppStatusUpdateEvent)
-      return this.equals((AppStatusUpdateEvent)that);
+    if (that instanceof ParagraphInfo)
+      return this.equals((ParagraphInfo)that);
     return false;
   }
 
-  public boolean equals(AppStatusUpdateEvent that) {
+  public boolean equals(ParagraphInfo that) {
     if (that == null)
       return false;
 
@@ -401,21 +401,21 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
         return false;
     }
 
-    boolean this_present_appId = true && this.isSetAppId();
-    boolean that_present_appId = true && that.isSetAppId();
-    if (this_present_appId || that_present_appId) {
-      if (!(this_present_appId && that_present_appId))
+    boolean this_present_paragraphTitle = true && this.isSetParagraphTitle();
+    boolean that_present_paragraphTitle = true && that.isSetParagraphTitle();
+    if (this_present_paragraphTitle || that_present_paragraphTitle) {
+      if (!(this_present_paragraphTitle && that_present_paragraphTitle))
         return false;
-      if (!this.appId.equals(that.appId))
+      if (!this.paragraphTitle.equals(that.paragraphTitle))
         return false;
     }
 
-    boolean this_present_status = true && this.isSetStatus();
-    boolean that_present_status = true && that.isSetStatus();
-    if (this_present_status || that_present_status) {
-      if (!(this_present_status && that_present_status))
+    boolean this_present_paragraphText = true && this.isSetParagraphText();
+    boolean that_present_paragraphText = true && that.isSetParagraphText();
+    if (this_present_paragraphText || that_present_paragraphText) {
+      if (!(this_present_paragraphText && that_present_paragraphText))
         return false;
-      if (!this.status.equals(that.status))
+      if (!this.paragraphText.equals(that.paragraphText))
         return false;
     }
 
@@ -436,21 +436,21 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     if (present_paragraphId)
       list.add(paragraphId);
 
-    boolean present_appId = true && (isSetAppId());
-    list.add(present_appId);
-    if (present_appId)
-      list.add(appId);
+    boolean present_paragraphTitle = true && (isSetParagraphTitle());
+    list.add(present_paragraphTitle);
+    if (present_paragraphTitle)
+      list.add(paragraphTitle);
 
-    boolean present_status = true && (isSetStatus());
-    list.add(present_status);
-    if (present_status)
-      list.add(status);
+    boolean present_paragraphText = true && (isSetParagraphText());
+    list.add(present_paragraphText);
+    if (present_paragraphText)
+      list.add(paragraphText);
 
     return list.hashCode();
   }
 
   @Override
-  public int compareTo(AppStatusUpdateEvent other) {
+  public int compareTo(ParagraphInfo other) {
     if (!getClass().equals(other.getClass())) {
       return getClass().getName().compareTo(other.getClass().getName());
     }
@@ -477,22 +477,22 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
         return lastComparison;
       }
     }
-    lastComparison = 
Boolean.valueOf(isSetAppId()).compareTo(other.isSetAppId());
+    lastComparison = 
Boolean.valueOf(isSetParagraphTitle()).compareTo(other.isSetParagraphTitle());
     if (lastComparison != 0) {
       return lastComparison;
     }
-    if (isSetAppId()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appId, 
other.appId);
+    if (isSetParagraphTitle()) {
+      lastComparison = 
org.apache.thrift.TBaseHelper.compareTo(this.paragraphTitle, 
other.paragraphTitle);
       if (lastComparison != 0) {
         return lastComparison;
       }
     }
-    lastComparison = 
Boolean.valueOf(isSetStatus()).compareTo(other.isSetStatus());
+    lastComparison = 
Boolean.valueOf(isSetParagraphText()).compareTo(other.isSetParagraphText());
     if (lastComparison != 0) {
       return lastComparison;
     }
-    if (isSetStatus()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, 
other.status);
+    if (isSetParagraphText()) {
+      lastComparison = 
org.apache.thrift.TBaseHelper.compareTo(this.paragraphText, 
other.paragraphText);
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -514,7 +514,7 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder("AppStatusUpdateEvent(");
+    StringBuilder sb = new StringBuilder("ParagraphInfo(");
     boolean first = true;
 
     sb.append("noteId:");
@@ -533,19 +533,19 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     }
     first = false;
     if (!first) sb.append(", ");
-    sb.append("appId:");
-    if (this.appId == null) {
+    sb.append("paragraphTitle:");
+    if (this.paragraphTitle == null) {
       sb.append("null");
     } else {
-      sb.append(this.appId);
+      sb.append(this.paragraphTitle);
     }
     first = false;
     if (!first) sb.append(", ");
-    sb.append("status:");
-    if (this.status == null) {
+    sb.append("paragraphText:");
+    if (this.paragraphText == null) {
       sb.append("null");
     } else {
-      sb.append(this.status);
+      sb.append(this.paragraphText);
     }
     first = false;
     sb.append(")");
@@ -573,15 +573,15 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
     }
   }
 
-  private static class AppStatusUpdateEventStandardSchemeFactory implements 
SchemeFactory {
-    public AppStatusUpdateEventStandardScheme getScheme() {
-      return new AppStatusUpdateEventStandardScheme();
+  private static class ParagraphInfoStandardSchemeFactory implements 
SchemeFactory {
+    public ParagraphInfoStandardScheme getScheme() {
+      return new ParagraphInfoStandardScheme();
     }
   }
 
-  private static class AppStatusUpdateEventStandardScheme extends 
StandardScheme<AppStatusUpdateEvent> {
+  private static class ParagraphInfoStandardScheme extends 
StandardScheme<ParagraphInfo> {
 
-    public void read(org.apache.thrift.protocol.TProtocol iprot, 
AppStatusUpdateEvent struct) throws org.apache.thrift.TException {
+    public void read(org.apache.thrift.protocol.TProtocol iprot, ParagraphInfo 
struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
       iprot.readStructBegin();
       while (true)
@@ -607,18 +607,18 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
             break;
-          case 3: // APP_ID
+          case 3: // PARAGRAPH_TITLE
             if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.appId = iprot.readString();
-              struct.setAppIdIsSet(true);
+              struct.paragraphTitle = iprot.readString();
+              struct.setParagraphTitleIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
             break;
-          case 4: // STATUS
+          case 4: // PARAGRAPH_TEXT
             if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.status = iprot.readString();
-              struct.setStatusIsSet(true);
+              struct.paragraphText = iprot.readString();
+              struct.setParagraphTextIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
@@ -634,7 +634,7 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
       struct.validate();
     }
 
-    public void write(org.apache.thrift.protocol.TProtocol oprot, 
AppStatusUpdateEvent struct) throws org.apache.thrift.TException {
+    public void write(org.apache.thrift.protocol.TProtocol oprot, 
ParagraphInfo struct) throws org.apache.thrift.TException {
       struct.validate();
 
       oprot.writeStructBegin(STRUCT_DESC);
@@ -648,14 +648,14 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
         oprot.writeString(struct.paragraphId);
         oprot.writeFieldEnd();
       }
-      if (struct.appId != null) {
-        oprot.writeFieldBegin(APP_ID_FIELD_DESC);
-        oprot.writeString(struct.appId);
+      if (struct.paragraphTitle != null) {
+        oprot.writeFieldBegin(PARAGRAPH_TITLE_FIELD_DESC);
+        oprot.writeString(struct.paragraphTitle);
         oprot.writeFieldEnd();
       }
-      if (struct.status != null) {
-        oprot.writeFieldBegin(STATUS_FIELD_DESC);
-        oprot.writeString(struct.status);
+      if (struct.paragraphText != null) {
+        oprot.writeFieldBegin(PARAGRAPH_TEXT_FIELD_DESC);
+        oprot.writeString(struct.paragraphText);
         oprot.writeFieldEnd();
       }
       oprot.writeFieldStop();
@@ -664,16 +664,16 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
 
   }
 
-  private static class AppStatusUpdateEventTupleSchemeFactory implements 
SchemeFactory {
-    public AppStatusUpdateEventTupleScheme getScheme() {
-      return new AppStatusUpdateEventTupleScheme();
+  private static class ParagraphInfoTupleSchemeFactory implements 
SchemeFactory {
+    public ParagraphInfoTupleScheme getScheme() {
+      return new ParagraphInfoTupleScheme();
     }
   }
 
-  private static class AppStatusUpdateEventTupleScheme extends 
TupleScheme<AppStatusUpdateEvent> {
+  private static class ParagraphInfoTupleScheme extends 
TupleScheme<ParagraphInfo> {
 
     @Override
-    public void write(org.apache.thrift.protocol.TProtocol prot, 
AppStatusUpdateEvent struct) throws org.apache.thrift.TException {
+    public void write(org.apache.thrift.protocol.TProtocol prot, ParagraphInfo 
struct) throws org.apache.thrift.TException {
       TTupleProtocol oprot = (TTupleProtocol) prot;
       BitSet optionals = new BitSet();
       if (struct.isSetNoteId()) {
@@ -682,10 +682,10 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
       if (struct.isSetParagraphId()) {
         optionals.set(1);
       }
-      if (struct.isSetAppId()) {
+      if (struct.isSetParagraphTitle()) {
         optionals.set(2);
       }
-      if (struct.isSetStatus()) {
+      if (struct.isSetParagraphText()) {
         optionals.set(3);
       }
       oprot.writeBitSet(optionals, 4);
@@ -695,16 +695,16 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
       if (struct.isSetParagraphId()) {
         oprot.writeString(struct.paragraphId);
       }
-      if (struct.isSetAppId()) {
-        oprot.writeString(struct.appId);
+      if (struct.isSetParagraphTitle()) {
+        oprot.writeString(struct.paragraphTitle);
       }
-      if (struct.isSetStatus()) {
-        oprot.writeString(struct.status);
+      if (struct.isSetParagraphText()) {
+        oprot.writeString(struct.paragraphText);
       }
     }
 
     @Override
-    public void read(org.apache.thrift.protocol.TProtocol prot, 
AppStatusUpdateEvent struct) throws org.apache.thrift.TException {
+    public void read(org.apache.thrift.protocol.TProtocol prot, ParagraphInfo 
struct) throws org.apache.thrift.TException {
       TTupleProtocol iprot = (TTupleProtocol) prot;
       BitSet incoming = iprot.readBitSet(4);
       if (incoming.get(0)) {
@@ -716,12 +716,12 @@ public class AppStatusUpdateEvent implements 
org.apache.thrift.TBase<AppStatusUp
         struct.setParagraphIdIsSet(true);
       }
       if (incoming.get(2)) {
-        struct.appId = iprot.readString();
-        struct.setAppIdIsSet(true);
+        struct.paragraphTitle = iprot.readString();
+        struct.setParagraphTitleIsSet(true);
       }
       if (incoming.get(3)) {
-        struct.status = iprot.readString();
-        struct.setStatusIsSet(true);
+        struct.paragraphText = iprot.readString();
+        struct.setParagraphTextIsSet(true);
       }
     }
   }
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RegisterInfo.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RegisterInfo.java
index 324b7c2..46fb9b0 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RegisterInfo.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RegisterInfo.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RegisterInfo implements org.apache.thrift.TBase<RegisterInfo, 
RegisterInfo._Fields>, java.io.Serializable, Cloneable, 
Comparable<RegisterInfo> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RegisterInfo");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
index 4d2bdb4..3cbbb3d 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteApplicationResult implements 
org.apache.thrift.TBase<RemoteApplicationResult, 
RemoteApplicationResult._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteApplicationResult> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteApplicationResult");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
index f1f36fc..4ff4896 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterContext implements 
org.apache.thrift.TBase<RemoteInterpreterContext, 
RemoteInterpreterContext._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteInterpreterContext> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteInterpreterContext");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
index c8bfa44..0fa6465 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterEvent implements 
org.apache.thrift.TBase<RemoteInterpreterEvent, 
RemoteInterpreterEvent._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteInterpreterEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteInterpreterEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventService.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventService.java
index 1290b74..4bbc8f7 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventService.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventService.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterEventService {
 
   public interface Iface {
@@ -86,6 +86,8 @@ public class RemoteInterpreterEventService {
 
     public ByteBuffer invokeMethod(String intpGroupId, String 
invokeMethodJson) throws org.apache.thrift.TException;
 
+    public List<ParagraphInfo> getParagraphList(String user, String noteId) 
throws ServiceException, org.apache.thrift.TException;
+
   }
 
   public interface AsyncIface {
@@ -120,6 +122,8 @@ public class RemoteInterpreterEventService {
 
     public void invokeMethod(String intpGroupId, String invokeMethodJson, 
org.apache.thrift.async.AsyncMethodCallback resultHandler) throws 
org.apache.thrift.TException;
 
+    public void getParagraphList(String user, String noteId, 
org.apache.thrift.async.AsyncMethodCallback resultHandler) throws 
org.apache.thrift.TException;
+
   }
 
   public static class Client extends org.apache.thrift.TServiceClient 
implements Iface {
@@ -458,6 +462,33 @@ public class RemoteInterpreterEventService {
       throw new 
org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT,
 "invokeMethod failed: unknown result");
     }
 
+    public List<ParagraphInfo> getParagraphList(String user, String noteId) 
throws ServiceException, org.apache.thrift.TException
+    {
+      send_getParagraphList(user, noteId);
+      return recv_getParagraphList();
+    }
+
+    public void send_getParagraphList(String user, String noteId) throws 
org.apache.thrift.TException
+    {
+      getParagraphList_args args = new getParagraphList_args();
+      args.setUser(user);
+      args.setNoteId(noteId);
+      sendBase("getParagraphList", args);
+    }
+
+    public List<ParagraphInfo> recv_getParagraphList() throws 
ServiceException, org.apache.thrift.TException
+    {
+      getParagraphList_result result = new getParagraphList_result();
+      receiveBase(result, "getParagraphList");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.e != null) {
+        throw result.e;
+      }
+      throw new 
org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT,
 "getParagraphList failed: unknown result");
+    }
+
   }
   public static class AsyncClient extends org.apache.thrift.async.TAsyncClient 
implements AsyncIface {
     public static class Factory implements 
org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
@@ -977,6 +1008,41 @@ public class RemoteInterpreterEventService {
       }
     }
 
+    public void getParagraphList(String user, String noteId, 
org.apache.thrift.async.AsyncMethodCallback resultHandler) throws 
org.apache.thrift.TException {
+      checkReady();
+      getParagraphList_call method_call = new getParagraphList_call(user, 
noteId, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class getParagraphList_call extends 
org.apache.thrift.async.TAsyncMethodCall {
+      private String user;
+      private String noteId;
+      public getParagraphList_call(String user, String noteId, 
org.apache.thrift.async.AsyncMethodCallback resultHandler, 
org.apache.thrift.async.TAsyncClient client, 
org.apache.thrift.protocol.TProtocolFactory protocolFactory, 
org.apache.thrift.transport.TNonblockingTransport transport) throws 
org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.user = user;
+        this.noteId = noteId;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws 
org.apache.thrift.TException {
+        prot.writeMessageBegin(new 
org.apache.thrift.protocol.TMessage("getParagraphList", 
org.apache.thrift.protocol.TMessageType.CALL, 0));
+        getParagraphList_args args = new getParagraphList_args();
+        args.setUser(user);
+        args.setNoteId(noteId);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public List<ParagraphInfo> getResult() throws ServiceException, 
org.apache.thrift.TException {
+        if (getState() != 
org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = 
new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = 
client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_getParagraphList();
+      }
+    }
+
   }
 
   public static class Processor<I extends Iface> extends 
org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
@@ -1005,6 +1071,7 @@ public class RemoteInterpreterEventService {
       processMap.put("getAllResources", new getAllResources());
       processMap.put("getResource", new getResource());
       processMap.put("invokeMethod", new invokeMethod());
+      processMap.put("getParagraphList", new getParagraphList());
       return processMap;
     }
 
@@ -1308,6 +1375,30 @@ public class RemoteInterpreterEventService {
       }
     }
 
+    public static class getParagraphList<I extends Iface> extends 
org.apache.thrift.ProcessFunction<I, getParagraphList_args> {
+      public getParagraphList() {
+        super("getParagraphList");
+      }
+
+      public getParagraphList_args getEmptyArgsInstance() {
+        return new getParagraphList_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public getParagraphList_result getResult(I iface, getParagraphList_args 
args) throws org.apache.thrift.TException {
+        getParagraphList_result result = new getParagraphList_result();
+        try {
+          result.success = iface.getParagraphList(args.user, args.noteId);
+        } catch (ServiceException e) {
+          result.e = e;
+        }
+        return result;
+      }
+    }
+
   }
 
   public static class AsyncProcessor<I extends AsyncIface> extends 
org.apache.thrift.TBaseAsyncProcessor<I> {
@@ -1336,6 +1427,7 @@ public class RemoteInterpreterEventService {
       processMap.put("getAllResources", new getAllResources());
       processMap.put("getResource", new getResource());
       processMap.put("invokeMethod", new invokeMethod());
+      processMap.put("getParagraphList", new getParagraphList());
       return processMap;
     }
 
@@ -2092,6 +2184,63 @@ public class RemoteInterpreterEventService {
       }
     }
 
+    public static class getParagraphList<I extends AsyncIface> extends 
org.apache.thrift.AsyncProcessFunction<I, getParagraphList_args, 
List<ParagraphInfo>> {
+      public getParagraphList() {
+        super("getParagraphList");
+      }
+
+      public getParagraphList_args getEmptyArgsInstance() {
+        return new getParagraphList_args();
+      }
+
+      public AsyncMethodCallback<List<ParagraphInfo>> getResultHandler(final 
AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<List<ParagraphInfo>>() { 
+          public void onComplete(List<ParagraphInfo> o) {
+            getParagraphList_result result = new getParagraphList_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, 
org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            getParagraphList_result result = new getParagraphList_result();
+            if (e instanceof ServiceException) {
+                        result.e = (ServiceException) e;
+                        result.setEIsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new 
org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR,
 e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, getParagraphList_args args, 
org.apache.thrift.async.AsyncMethodCallback<List<ParagraphInfo>> resultHandler) 
throws TException {
+        iface.getParagraphList(args.user, args.noteId,resultHandler);
+      }
+    }
+
   }
 
   public static class registerInterpreterProcess_args implements 
org.apache.thrift.TBase<registerInterpreterProcess_args, 
registerInterpreterProcess_args._Fields>, java.io.Serializable, Cloneable, 
Comparable<registerInterpreterProcess_args>   {
@@ -12412,4 +12561,992 @@ public class RemoteInterpreterEventService {
 
   }
 
+  public static class getParagraphList_args implements 
org.apache.thrift.TBase<getParagraphList_args, getParagraphList_args._Fields>, 
java.io.Serializable, Cloneable, Comparable<getParagraphList_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("getParagraphList_args");
+
+    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = 
new org.apache.thrift.protocol.TField("user", 
org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NOTE_ID_FIELD_DESC 
= new org.apache.thrift.protocol.TField("noteId", 
org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes 
= new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new 
getParagraphList_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new 
getParagraphList_argsTupleSchemeFactory());
+    }
+
+    public String user; // required
+    public String noteId; // required
+
+    /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      USER((short)1, "user"),
+      NOTE_ID((short)2, "noteId");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, 
_Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not 
found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // USER
+            return USER;
+          case 2: // NOTE_ID
+            return NOTE_ID;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + 
fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, 
org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new 
EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.USER, new 
org.apache.thrift.meta_data.FieldMetaData("user", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NOTE_ID, new 
org.apache.thrift.meta_data.FieldMetaData("noteId", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getParagraphList_args.class,
 metaDataMap);
+    }
+
+    public getParagraphList_args() {
+    }
+
+    public getParagraphList_args(
+      String user,
+      String noteId)
+    {
+      this();
+      this.user = user;
+      this.noteId = noteId;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getParagraphList_args(getParagraphList_args other) {
+      if (other.isSetUser()) {
+        this.user = other.user;
+      }
+      if (other.isSetNoteId()) {
+        this.noteId = other.noteId;
+      }
+    }
+
+    public getParagraphList_args deepCopy() {
+      return new getParagraphList_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.user = null;
+      this.noteId = null;
+    }
+
+    public String getUser() {
+      return this.user;
+    }
+
+    public getParagraphList_args setUser(String user) {
+      this.user = user;
+      return this;
+    }
+
+    public void unsetUser() {
+      this.user = null;
+    }
+
+    /** Returns true if field user is set (has been assigned a value) and 
false otherwise */
+    public boolean isSetUser() {
+      return this.user != null;
+    }
+
+    public void setUserIsSet(boolean value) {
+      if (!value) {
+        this.user = null;
+      }
+    }
+
+    public String getNoteId() {
+      return this.noteId;
+    }
+
+    public getParagraphList_args setNoteId(String noteId) {
+      this.noteId = noteId;
+      return this;
+    }
+
+    public void unsetNoteId() {
+      this.noteId = null;
+    }
+
+    /** Returns true if field noteId is set (has been assigned a value) and 
false otherwise */
+    public boolean isSetNoteId() {
+      return this.noteId != null;
+    }
+
+    public void setNoteIdIsSet(boolean value) {
+      if (!value) {
+        this.noteId = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case USER:
+        if (value == null) {
+          unsetUser();
+        } else {
+          setUser((String)value);
+        }
+        break;
+
+      case NOTE_ID:
+        if (value == null) {
+          unsetNoteId();
+        } else {
+          setNoteId((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case USER:
+        return getUser();
+
+      case NOTE_ID:
+        return getNoteId();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been 
assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case USER:
+        return isSetUser();
+      case NOTE_ID:
+        return isSetNoteId();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getParagraphList_args)
+        return this.equals((getParagraphList_args)that);
+      return false;
+    }
+
+    public boolean equals(getParagraphList_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_user = true && this.isSetUser();
+      boolean that_present_user = true && that.isSetUser();
+      if (this_present_user || that_present_user) {
+        if (!(this_present_user && that_present_user))
+          return false;
+        if (!this.user.equals(that.user))
+          return false;
+      }
+
+      boolean this_present_noteId = true && this.isSetNoteId();
+      boolean that_present_noteId = true && that.isSetNoteId();
+      if (this_present_noteId || that_present_noteId) {
+        if (!(this_present_noteId && that_present_noteId))
+          return false;
+        if (!this.noteId.equals(that.noteId))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_noteId = true && (isSetNoteId());
+      list.add(present_noteId);
+      if (present_noteId)
+        list.add(noteId);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getParagraphList_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 
Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUser()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, 
other.user);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = 
Boolean.valueOf(isSetNoteId()).compareTo(other.isSetNoteId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNoteId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.noteId, 
other.noteId);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws 
org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws 
org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getParagraphList_args(");
+      boolean first = true;
+
+      sb.append("user:");
+      if (this.user == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.user);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("noteId:");
+      if (this.noteId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.noteId);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws 
java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new 
org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws 
java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new 
org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getParagraphList_argsStandardSchemeFactory implements 
SchemeFactory {
+      public getParagraphList_argsStandardScheme getScheme() {
+        return new getParagraphList_argsStandardScheme();
+      }
+    }
+
+    private static class getParagraphList_argsStandardScheme extends 
StandardScheme<getParagraphList_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, 
getParagraphList_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // USER
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) 
{
+                struct.user = iprot.readString();
+                struct.setUserIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+              }
+              break;
+            case 2: // NOTE_ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) 
{
+                struct.noteId = iprot.readString();
+                struct.setNoteIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked 
in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, 
getParagraphList_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.user != null) {
+          oprot.writeFieldBegin(USER_FIELD_DESC);
+          oprot.writeString(struct.user);
+          oprot.writeFieldEnd();
+        }
+        if (struct.noteId != null) {
+          oprot.writeFieldBegin(NOTE_ID_FIELD_DESC);
+          oprot.writeString(struct.noteId);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getParagraphList_argsTupleSchemeFactory implements 
SchemeFactory {
+      public getParagraphList_argsTupleScheme getScheme() {
+        return new getParagraphList_argsTupleScheme();
+      }
+    }
+
+    private static class getParagraphList_argsTupleScheme extends 
TupleScheme<getParagraphList_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, 
getParagraphList_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetUser()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNoteId()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetUser()) {
+          oprot.writeString(struct.user);
+        }
+        if (struct.isSetNoteId()) {
+          oprot.writeString(struct.noteId);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, 
getParagraphList_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.user = iprot.readString();
+          struct.setUserIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.noteId = iprot.readString();
+          struct.setNoteIdIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getParagraphList_result implements 
org.apache.thrift.TBase<getParagraphList_result, 
getParagraphList_result._Fields>, java.io.Serializable, Cloneable, 
Comparable<getParagraphList_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("getParagraphList_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC 
= new org.apache.thrift.protocol.TField("success", 
org.apache.thrift.protocol.TType.LIST, (short)0);
+    private static final org.apache.thrift.protocol.TField E_FIELD_DESC = new 
org.apache.thrift.protocol.TField("e", org.apache.thrift.protocol.TType.STRUCT, 
(short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes 
= new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new 
getParagraphList_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new 
getParagraphList_resultTupleSchemeFactory());
+    }
+
+    public List<ParagraphInfo> success; // required
+    public ServiceException e; // required
+
+    /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      E((short)1, "e");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, 
_Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not 
found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // E
+            return E;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + 
fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, 
org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new 
EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new 
org.apache.thrift.meta_data.FieldMetaData("success", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new 
org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+              new 
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
 ParagraphInfo.class))));
+      tmpMap.put(_Fields.E, new org.apache.thrift.meta_data.FieldMetaData("e", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getParagraphList_result.class,
 metaDataMap);
+    }
+
+    public getParagraphList_result() {
+    }
+
+    public getParagraphList_result(
+      List<ParagraphInfo> success,
+      ServiceException e)
+    {
+      this();
+      this.success = success;
+      this.e = e;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getParagraphList_result(getParagraphList_result other) {
+      if (other.isSetSuccess()) {
+        List<ParagraphInfo> __this__success = new 
ArrayList<ParagraphInfo>(other.success.size());
+        for (ParagraphInfo other_element : other.success) {
+          __this__success.add(new ParagraphInfo(other_element));
+        }
+        this.success = __this__success;
+      }
+      if (other.isSetE()) {
+        this.e = new ServiceException(other.e);
+      }
+    }
+
+    public getParagraphList_result deepCopy() {
+      return new getParagraphList_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.e = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public java.util.Iterator<ParagraphInfo> getSuccessIterator() {
+      return (this.success == null) ? null : this.success.iterator();
+    }
+
+    public void addToSuccess(ParagraphInfo elem) {
+      if (this.success == null) {
+        this.success = new ArrayList<ParagraphInfo>();
+      }
+      this.success.add(elem);
+    }
+
+    public List<ParagraphInfo> getSuccess() {
+      return this.success;
+    }
+
+    public getParagraphList_result setSuccess(List<ParagraphInfo> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and 
false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public ServiceException getE() {
+      return this.e;
+    }
+
+    public getParagraphList_result setE(ServiceException e) {
+      this.e = e;
+      return this;
+    }
+
+    public void unsetE() {
+      this.e = null;
+    }
+
+    /** Returns true if field e is set (has been assigned a value) and false 
otherwise */
+    public boolean isSetE() {
+      return this.e != null;
+    }
+
+    public void setEIsSet(boolean value) {
+      if (!value) {
+        this.e = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((List<ParagraphInfo>)value);
+        }
+        break;
+
+      case E:
+        if (value == null) {
+          unsetE();
+        } else {
+          setE((ServiceException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case E:
+        return getE();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been 
assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case E:
+        return isSetE();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getParagraphList_result)
+        return this.equals((getParagraphList_result)that);
+      return false;
+    }
+
+    public boolean equals(getParagraphList_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_e = true && this.isSetE();
+      boolean that_present_e = true && that.isSetE();
+      if (this_present_e || that_present_e) {
+        if (!(this_present_e && that_present_e))
+          return false;
+        if (!this.e.equals(that.e))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_e = true && (isSetE());
+      list.add(present_e);
+      if (present_e)
+        list.add(e);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getParagraphList_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 
Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, 
other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetE()).compareTo(other.isSetE());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetE()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.e, 
other.e);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws 
org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws 
org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getParagraphList_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("e:");
+      if (this.e == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.e);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws 
java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new 
org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws 
java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new 
org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getParagraphList_resultStandardSchemeFactory 
implements SchemeFactory {
+      public getParagraphList_resultStandardScheme getScheme() {
+        return new getParagraphList_resultStandardScheme();
+      }
+    }
+
+    private static class getParagraphList_resultStandardScheme extends 
StandardScheme<getParagraphList_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, 
getParagraphList_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+                {
+                  org.apache.thrift.protocol.TList _list32 = 
iprot.readListBegin();
+                  struct.success = new ArrayList<ParagraphInfo>(_list32.size);
+                  ParagraphInfo _elem33;
+                  for (int _i34 = 0; _i34 < _list32.size; ++_i34)
+                  {
+                    _elem33 = new ParagraphInfo();
+                    _elem33.read(iprot);
+                    struct.success.add(_elem33);
+                  }
+                  iprot.readListEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+              }
+              break;
+            case 1: // E
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) 
{
+                struct.e = new ServiceException();
+                struct.e.read(iprot);
+                struct.setEIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked 
in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, 
getParagraphList_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeListBegin(new 
org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, 
struct.success.size()));
+            for (ParagraphInfo _iter35 : struct.success)
+            {
+              _iter35.write(oprot);
+            }
+            oprot.writeListEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.e != null) {
+          oprot.writeFieldBegin(E_FIELD_DESC);
+          struct.e.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getParagraphList_resultTupleSchemeFactory implements 
SchemeFactory {
+      public getParagraphList_resultTupleScheme getScheme() {
+        return new getParagraphList_resultTupleScheme();
+      }
+    }
+
+    private static class getParagraphList_resultTupleScheme extends 
TupleScheme<getParagraphList_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, 
getParagraphList_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetE()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (ParagraphInfo _iter36 : struct.success)
+            {
+              _iter36.write(oprot);
+            }
+          }
+        }
+        if (struct.isSetE()) {
+          struct.e.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, 
getParagraphList_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TList _list37 = new 
org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, 
iprot.readI32());
+            struct.success = new ArrayList<ParagraphInfo>(_list37.size);
+            ParagraphInfo _elem38;
+            for (int _i39 = 0; _i39 < _list37.size; ++_i39)
+            {
+              _elem38 = new ParagraphInfo();
+              _elem38.read(iprot);
+              struct.success.add(_elem38);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.e = new ServiceException();
+          struct.e.read(iprot);
+          struct.setEIsSet(true);
+        }
+      }
+    }
+
+  }
+
 }
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
index 2c863c2..0f9aeca 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterResult implements 
org.apache.thrift.TBase<RemoteInterpreterResult, 
RemoteInterpreterResult._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteInterpreterResult> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteInterpreterResult");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
index f88993c..5809e4f 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<RemoteInterpreterResultMessage, 
RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteInterpreterResultMessage> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java
index 3dd8875..396fc94 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RemoteInterpreterService {
 
   public interface Iface {
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RunParagraphsEvent.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RunParagraphsEvent.java
index 1387635..3c0da8a 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RunParagraphsEvent.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RunParagraphsEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
 public class RunParagraphsEvent implements 
org.apache.thrift.TBase<RunParagraphsEvent, RunParagraphsEvent._Fields>, 
java.io.Serializable, Cloneable, Comparable<RunParagraphsEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RunParagraphsEvent");
 
diff --git 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ServiceException.java
similarity index 53%
copy from 
zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
copy to 
zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ServiceException.java
index f88993c..fe6b593 100644
--- 
a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
+++ 
b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ServiceException.java
@@ -51,26 +51,23 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2018-8-9")
-public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<RemoteInterpreterResultMessage, 
RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, 
Comparable<RemoteInterpreterResultMessage> {
-  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage");
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = 
"2019-3-4")
+public class ServiceException extends TException implements 
org.apache.thrift.TBase<ServiceException, ServiceException._Fields>, 
java.io.Serializable, Cloneable, Comparable<ServiceException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("ServiceException");
 
-  private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new 
org.apache.thrift.protocol.TField("type", 
org.apache.thrift.protocol.TType.STRING, (short)1);
-  private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new 
org.apache.thrift.protocol.TField("data", 
org.apache.thrift.protocol.TType.STRING, (short)2);
+  private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = 
new org.apache.thrift.protocol.TField("message", 
org.apache.thrift.protocol.TType.STRING, (short)1);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = 
new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
-    schemes.put(StandardScheme.class, new 
RemoteInterpreterResultMessageStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new 
RemoteInterpreterResultMessageTupleSchemeFactory());
+    schemes.put(StandardScheme.class, new 
ServiceExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new ServiceExceptionTupleSchemeFactory());
   }
 
-  public String type; // required
-  public String data; // required
+  public String message; // required
 
   /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-    TYPE((short)1, "type"),
-    DATA((short)2, "data");
+    MESSAGE((short)1, "message");
 
     private static final Map<String, _Fields> byName = new HashMap<String, 
_Fields>();
 
@@ -85,10 +82,8 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
      */
     public static _Fields findByThriftId(int fieldId) {
       switch(fieldId) {
-        case 1: // TYPE
-          return TYPE;
-        case 2: // DATA
-          return DATA;
+        case 1: // MESSAGE
+          return MESSAGE;
         default:
           return null;
       }
@@ -132,111 +127,71 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> 
metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new 
EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-    tmpMap.put(_Fields.TYPE, new 
org.apache.thrift.meta_data.FieldMetaData("type", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-    tmpMap.put(_Fields.DATA, new 
org.apache.thrift.meta_data.FieldMetaData("data", 
org.apache.thrift.TFieldRequirementType.DEFAULT, 
+    tmpMap.put(_Fields.MESSAGE, new 
org.apache.thrift.meta_data.FieldMetaData("message", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     metaDataMap = Collections.unmodifiableMap(tmpMap);
-    
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RemoteInterpreterResultMessage.class,
 metaDataMap);
+    
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ServiceException.class,
 metaDataMap);
   }
 
-  public RemoteInterpreterResultMessage() {
+  public ServiceException() {
   }
 
-  public RemoteInterpreterResultMessage(
-    String type,
-    String data)
+  public ServiceException(
+    String message)
   {
     this();
-    this.type = type;
-    this.data = data;
+    this.message = message;
   }
 
   /**
    * Performs a deep copy on <i>other</i>.
    */
-  public RemoteInterpreterResultMessage(RemoteInterpreterResultMessage other) {
-    if (other.isSetType()) {
-      this.type = other.type;
-    }
-    if (other.isSetData()) {
-      this.data = other.data;
+  public ServiceException(ServiceException other) {
+    if (other.isSetMessage()) {
+      this.message = other.message;
     }
   }
 
-  public RemoteInterpreterResultMessage deepCopy() {
-    return new RemoteInterpreterResultMessage(this);
+  public ServiceException deepCopy() {
+    return new ServiceException(this);
   }
 
   @Override
   public void clear() {
-    this.type = null;
-    this.data = null;
-  }
-
-  public String getType() {
-    return this.type;
-  }
-
-  public RemoteInterpreterResultMessage setType(String type) {
-    this.type = type;
-    return this;
-  }
-
-  public void unsetType() {
-    this.type = null;
-  }
-
-  /** Returns true if field type is set (has been assigned a value) and false 
otherwise */
-  public boolean isSetType() {
-    return this.type != null;
-  }
-
-  public void setTypeIsSet(boolean value) {
-    if (!value) {
-      this.type = null;
-    }
+    this.message = null;
   }
 
-  public String getData() {
-    return this.data;
+  public String getMessage() {
+    return this.message;
   }
 
-  public RemoteInterpreterResultMessage setData(String data) {
-    this.data = data;
+  public ServiceException setMessage(String message) {
+    this.message = message;
     return this;
   }
 
-  public void unsetData() {
-    this.data = null;
+  public void unsetMessage() {
+    this.message = null;
   }
 
-  /** Returns true if field data is set (has been assigned a value) and false 
otherwise */
-  public boolean isSetData() {
-    return this.data != null;
+  /** Returns true if field message is set (has been assigned a value) and 
false otherwise */
+  public boolean isSetMessage() {
+    return this.message != null;
   }
 
-  public void setDataIsSet(boolean value) {
+  public void setMessageIsSet(boolean value) {
     if (!value) {
-      this.data = null;
+      this.message = null;
     }
   }
 
   public void setFieldValue(_Fields field, Object value) {
     switch (field) {
-    case TYPE:
-      if (value == null) {
-        unsetType();
-      } else {
-        setType((String)value);
-      }
-      break;
-
-    case DATA:
+    case MESSAGE:
       if (value == null) {
-        unsetData();
+        unsetMessage();
       } else {
-        setData((String)value);
+        setMessage((String)value);
       }
       break;
 
@@ -245,11 +200,8 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
 
   public Object getFieldValue(_Fields field) {
     switch (field) {
-    case TYPE:
-      return getType();
-
-    case DATA:
-      return getData();
+    case MESSAGE:
+      return getMessage();
 
     }
     throw new IllegalStateException();
@@ -262,10 +214,8 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
     }
 
     switch (field) {
-    case TYPE:
-      return isSetType();
-    case DATA:
-      return isSetData();
+    case MESSAGE:
+      return isSetMessage();
     }
     throw new IllegalStateException();
   }
@@ -274,30 +224,21 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
   public boolean equals(Object that) {
     if (that == null)
       return false;
-    if (that instanceof RemoteInterpreterResultMessage)
-      return this.equals((RemoteInterpreterResultMessage)that);
+    if (that instanceof ServiceException)
+      return this.equals((ServiceException)that);
     return false;
   }
 
-  public boolean equals(RemoteInterpreterResultMessage that) {
+  public boolean equals(ServiceException that) {
     if (that == null)
       return false;
 
-    boolean this_present_type = true && this.isSetType();
-    boolean that_present_type = true && that.isSetType();
-    if (this_present_type || that_present_type) {
-      if (!(this_present_type && that_present_type))
-        return false;
-      if (!this.type.equals(that.type))
-        return false;
-    }
-
-    boolean this_present_data = true && this.isSetData();
-    boolean that_present_data = true && that.isSetData();
-    if (this_present_data || that_present_data) {
-      if (!(this_present_data && that_present_data))
+    boolean this_present_message = true && this.isSetMessage();
+    boolean that_present_message = true && that.isSetMessage();
+    if (this_present_message || that_present_message) {
+      if (!(this_present_message && that_present_message))
         return false;
-      if (!this.data.equals(that.data))
+      if (!this.message.equals(that.message))
         return false;
     }
 
@@ -308,43 +249,28 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
   public int hashCode() {
     List<Object> list = new ArrayList<Object>();
 
-    boolean present_type = true && (isSetType());
-    list.add(present_type);
-    if (present_type)
-      list.add(type);
-
-    boolean present_data = true && (isSetData());
-    list.add(present_data);
-    if (present_data)
-      list.add(data);
+    boolean present_message = true && (isSetMessage());
+    list.add(present_message);
+    if (present_message)
+      list.add(message);
 
     return list.hashCode();
   }
 
   @Override
-  public int compareTo(RemoteInterpreterResultMessage other) {
+  public int compareTo(ServiceException other) {
     if (!getClass().equals(other.getClass())) {
       return getClass().getName().compareTo(other.getClass().getName());
     }
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
+    lastComparison = 
Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage());
     if (lastComparison != 0) {
       return lastComparison;
     }
-    if (isSetType()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, 
other.type);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    lastComparison = Boolean.valueOf(isSetData()).compareTo(other.isSetData());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetData()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, 
other.data);
+    if (isSetMessage()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, 
other.message);
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -366,22 +292,14 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder("RemoteInterpreterResultMessage(");
+    StringBuilder sb = new StringBuilder("ServiceException(");
     boolean first = true;
 
-    sb.append("type:");
-    if (this.type == null) {
+    sb.append("message:");
+    if (this.message == null) {
       sb.append("null");
     } else {
-      sb.append(this.type);
-    }
-    first = false;
-    if (!first) sb.append(", ");
-    sb.append("data:");
-    if (this.data == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.data);
+      sb.append(this.message);
     }
     first = false;
     sb.append(")");
@@ -390,6 +308,9 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
 
   public void validate() throws org.apache.thrift.TException {
     // check for required fields
+    if (message == null) {
+      throw new org.apache.thrift.protocol.TProtocolException("Required field 
'message' was not present! Struct: " + toString());
+    }
     // check for sub-struct validity
   }
 
@@ -409,15 +330,15 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
     }
   }
 
-  private static class RemoteInterpreterResultMessageStandardSchemeFactory 
implements SchemeFactory {
-    public RemoteInterpreterResultMessageStandardScheme getScheme() {
-      return new RemoteInterpreterResultMessageStandardScheme();
+  private static class ServiceExceptionStandardSchemeFactory implements 
SchemeFactory {
+    public ServiceExceptionStandardScheme getScheme() {
+      return new ServiceExceptionStandardScheme();
     }
   }
 
-  private static class RemoteInterpreterResultMessageStandardScheme extends 
StandardScheme<RemoteInterpreterResultMessage> {
+  private static class ServiceExceptionStandardScheme extends 
StandardScheme<ServiceException> {
 
-    public void read(org.apache.thrift.protocol.TProtocol iprot, 
RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+    public void read(org.apache.thrift.protocol.TProtocol iprot, 
ServiceException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
       iprot.readStructBegin();
       while (true)
@@ -427,18 +348,10 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
           break;
         }
         switch (schemeField.id) {
-          case 1: // TYPE
+          case 1: // MESSAGE
             if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.type = iprot.readString();
-              struct.setTypeIsSet(true);
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
-            }
-            break;
-          case 2: // DATA
-            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.data = iprot.readString();
-              struct.setDataIsSet(true);
+              struct.message = iprot.readString();
+              struct.setMessageIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
@@ -454,18 +367,13 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
       struct.validate();
     }
 
-    public void write(org.apache.thrift.protocol.TProtocol oprot, 
RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+    public void write(org.apache.thrift.protocol.TProtocol oprot, 
ServiceException struct) throws org.apache.thrift.TException {
       struct.validate();
 
       oprot.writeStructBegin(STRUCT_DESC);
-      if (struct.type != null) {
-        oprot.writeFieldBegin(TYPE_FIELD_DESC);
-        oprot.writeString(struct.type);
-        oprot.writeFieldEnd();
-      }
-      if (struct.data != null) {
-        oprot.writeFieldBegin(DATA_FIELD_DESC);
-        oprot.writeString(struct.data);
+      if (struct.message != null) {
+        oprot.writeFieldBegin(MESSAGE_FIELD_DESC);
+        oprot.writeString(struct.message);
         oprot.writeFieldEnd();
       }
       oprot.writeFieldStop();
@@ -474,45 +382,25 @@ public class RemoteInterpreterResultMessage implements 
org.apache.thrift.TBase<R
 
   }
 
-  private static class RemoteInterpreterResultMessageTupleSchemeFactory 
implements SchemeFactory {
-    public RemoteInterpreterResultMessageTupleScheme getScheme() {
-      return new RemoteInterpreterResultMessageTupleScheme();
+  private static class ServiceExceptionTupleSchemeFactory implements 
SchemeFactory {
+    public ServiceExceptionTupleScheme getScheme() {
+      return new ServiceExceptionTupleScheme();
     }
   }
 
-  private static class RemoteInterpreterResultMessageTupleScheme extends 
TupleScheme<RemoteInterpreterResultMessage> {
+  private static class ServiceExceptionTupleScheme extends 
TupleScheme<ServiceException> {
 
     @Override
-    public void write(org.apache.thrift.protocol.TProtocol prot, 
RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+    public void write(org.apache.thrift.protocol.TProtocol prot, 
ServiceException struct) throws org.apache.thrift.TException {
       TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
-      if (struct.isSetType()) {
-        optionals.set(0);
-      }
-      if (struct.isSetData()) {
-        optionals.set(1);
-      }
-      oprot.writeBitSet(optionals, 2);
-      if (struct.isSetType()) {
-        oprot.writeString(struct.type);
-      }
-      if (struct.isSetData()) {
-        oprot.writeString(struct.data);
-      }
+      oprot.writeString(struct.message);
     }
 
     @Override
-    public void read(org.apache.thrift.protocol.TProtocol prot, 
RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+    public void read(org.apache.thrift.protocol.TProtocol prot, 
ServiceException struct) throws org.apache.thrift.TException {
       TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
-      if (incoming.get(0)) {
-        struct.type = iprot.readString();
-        struct.setTypeIsSet(true);
-      }
-      if (incoming.get(1)) {
-        struct.data = iprot.readString();
-        struct.setDataIsSet(true);
-      }
+      struct.message = iprot.readString();
+      struct.setMessageIsSet(true);
     }
   }
 
diff --git 
a/zeppelin-interpreter/src/main/thrift/RemoteInterpreterEventService.thrift 
b/zeppelin-interpreter/src/main/thrift/RemoteInterpreterEventService.thrift
index a99d0ee..6470a67 100644
--- a/zeppelin-interpreter/src/main/thrift/RemoteInterpreterEventService.thrift
+++ b/zeppelin-interpreter/src/main/thrift/RemoteInterpreterEventService.thrift
@@ -86,6 +86,17 @@ struct AppStatusUpdateEvent {
   4: string status
 }
 
+struct ParagraphInfo {
+  1: string noteId,
+  2: string paragraphId,
+  3: string paragraphTitle,
+  4: string paragraphText
+}
+
+exception ServiceException{
+  1: required string message;
+}
+
 service RemoteInterpreterEventService {
   void registerInterpreterProcess(1: RegisterInfo registerInfo);
   void appendOutput(1: OutputAppendEvent event);
@@ -107,4 +118,6 @@ service RemoteInterpreterEventService {
   list<string> getAllResources(1: string intpGroupId);
   binary getResource(1: string resourceIdJson);
   binary invokeMethod(1: string intpGroupId, 2: string invokeMethodJson);
+
+  list<ParagraphInfo> getParagraphList(1: string user, 2: string noteId) 
throws (1: ServiceException e);
 }
\ No newline at end of file
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 21cb0ff..f8fc2f0 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
@@ -29,6 +29,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -40,6 +41,7 @@ import javax.inject.Provider;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.thrift.TException;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectRegistry;
@@ -55,6 +57,8 @@ import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
 import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
+import org.apache.zeppelin.interpreter.thrift.ServiceException;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteEventListener;
 import org.apache.zeppelin.notebook.NoteInfo;
@@ -68,6 +72,7 @@ import 
org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl.Revision
 import org.apache.zeppelin.notebook.socket.Message;
 import org.apache.zeppelin.notebook.socket.Message.OP;
 import org.apache.zeppelin.rest.exception.ForbiddenException;
+import org.apache.zeppelin.rest.exception.NoteNotFoundException;
 import org.apache.zeppelin.scheduler.Job.Status;
 import org.apache.zeppelin.service.ConfigurationService;
 import org.apache.zeppelin.service.JobManagerService;
@@ -1844,6 +1849,42 @@ public class NotebookServer extends WebSocketServlet
     }
   }
 
+  @Override
+  public List<ParagraphInfo> getParagraphList(String user, String noteId)
+      throws TException, ServiceException {
+    Notebook notebook = getNotebook();
+    Note note = notebook.getNote(noteId);
+    if (null == note) {
+      throw new ServiceException("Not found this note : " + noteId);
+    }
+
+    // Check READER permission
+    Set<String> userAndRoles = new HashSet<>();
+    userAndRoles.add(user);
+    NotebookAuthorization notebookAuthorization = 
notebook.getNotebookAuthorization();
+    boolean isAllowed = notebookAuthorization.isReader(noteId, userAndRoles);
+    Set<String> allowed = notebookAuthorization.getReaders(noteId);
+    if (false == isAllowed) {
+      String errorMsg = "Insufficient privileges to READER note. " +
+          "Allowed users or roles: " + allowed;
+      throw new ServiceException(errorMsg);
+    }
+
+    // Convert Paragraph to ParagraphInfo
+    List<ParagraphInfo> paragraphInfos = new ArrayList();
+    List<Paragraph> paragraphs = note.getParagraphs();
+    for (Iterator<Paragraph> iter = paragraphs.iterator(); iter.hasNext();) {
+      Paragraph paragraph = iter.next();
+      ParagraphInfo paraInfo = new ParagraphInfo();
+      paraInfo.setNoteId(noteId);
+      paraInfo.setParagraphId(paragraph.getId());
+      paraInfo.setParagraphTitle(paragraph.getTitle());
+      paraInfo.setParagraphText(paragraph.getText());
+      paragraphInfos.add(paraInfo);
+    }
+    return paragraphInfos;
+  }
+
   private void broadcastNoteForms(Note note) {
     GUI formsSettings = new GUI();
     formsSettings.setForms(note.getNoteForms());
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 b26110c..0760e6a 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
@@ -20,6 +20,7 @@ import static java.util.Arrays.asList;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -35,15 +36,21 @@ import static org.mockito.Mockito.when;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
+
+import org.apache.thrift.TException;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectBuilder;
 import org.apache.zeppelin.interpreter.InterpreterGroup;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
+import org.apache.zeppelin.interpreter.thrift.ServiceException;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
@@ -627,6 +634,67 @@ public class NotebookServerTest extends 
AbstractTestRestApi {
     assertEquals(list.get(0).get("jobLabel"), "jobLabel_value");
   }
 
+  @Test
+  public void testGetParagraphList() {
+    Note note = null;
+
+    try {
+      note = notebook.createNote("note1", anonymous);
+      Paragraph p1 = note.addNewParagraph(anonymous);
+      p1.setText("%md start remote interpreter process");
+      p1.setAuthenticationInfo(anonymous);
+      notebookServer.getNotebook().saveNote(note, anonymous);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    String noteId = note.getId();
+    String user1Id = "user1", user2Id = "user2";
+
+    NotebookAuthorization notebookAuthorization = 
NotebookAuthorization.getInstance();
+
+    // test user1 can get anonymous's note
+    List<ParagraphInfo> paragraphList0 = null;
+    try {
+      paragraphList0 = notebookServer.getParagraphList(user1Id, noteId);
+    } catch (ServiceException e) {
+      e.printStackTrace();
+    } catch (TException e) {
+      e.printStackTrace();
+    }
+    assertNotNull(user1Id + " can get anonymous's note", paragraphList0);
+
+    // test user1 cannot get user2's note
+    notebookAuthorization.setOwners(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    notebookAuthorization.setReaders(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    notebookAuthorization.setRunners(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    notebookAuthorization.setWriters(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    List<ParagraphInfo> paragraphList1 = null;
+    try {
+      paragraphList1 = notebookServer.getParagraphList(user1Id, noteId);
+    } catch (ServiceException e) {
+      e.printStackTrace();
+    } catch (TException e) {
+      e.printStackTrace();
+    }
+    assertNull(user1Id + " cannot get " + user2Id + "'s note", paragraphList1);
+
+    // test user1 can get user2's shared note
+    notebookAuthorization.setOwners(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    notebookAuthorization.setReaders(noteId, new 
HashSet<>(Arrays.asList(user1Id, user2Id)));
+    notebookAuthorization.setRunners(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    notebookAuthorization.setWriters(noteId, new 
HashSet<>(Arrays.asList(user2Id)));
+    List<ParagraphInfo> paragraphList2 = null;
+    try {
+      paragraphList2 = notebookServer.getParagraphList(user1Id, noteId);
+    } catch (ServiceException e) {
+      e.printStackTrace();
+    } catch (TException e) {
+      e.printStackTrace();
+    }
+    assertNotNull(user1Id + " can get " + user2Id + "'s shared note", 
paragraphList2);
+  }
+
   private NotebookSocket createWebSocket() {
     NotebookSocket sock = mock(NotebookSocket.class);
     when(sock.getRequest()).thenReturn(mockRequest);
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/RemoteInterpreterEventServer.java
 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/RemoteInterpreterEventServer.java
index d7dd304..5932c12 100644
--- 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/RemoteInterpreterEventServer.java
+++ 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/RemoteInterpreterEventServer.java
@@ -28,13 +28,13 @@ import org.apache.zeppelin.helium.ApplicationEventListener;
 import org.apache.zeppelin.interpreter.remote.AppendOutputRunner;
 import org.apache.zeppelin.interpreter.remote.InvokeResourceMethodEventMessage;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObject;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils;
 import org.apache.zeppelin.interpreter.thrift.AppOutputAppendEvent;
 import org.apache.zeppelin.interpreter.thrift.AppOutputUpdateEvent;
 import org.apache.zeppelin.interpreter.thrift.AppStatusUpdateEvent;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
 import org.apache.zeppelin.interpreter.thrift.RegisterInfo;
 import org.apache.zeppelin.interpreter.thrift.OutputAppendEvent;
 import org.apache.zeppelin.interpreter.thrift.OutputUpdateAllEvent;
@@ -43,12 +43,13 @@ import 
org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEventService;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterResultMessage;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
 import org.apache.zeppelin.interpreter.thrift.RunParagraphsEvent;
+import org.apache.zeppelin.interpreter.thrift.ServiceException;
 import org.apache.zeppelin.resource.RemoteResource;
 import org.apache.zeppelin.resource.Resource;
 import org.apache.zeppelin.resource.ResourceId;
 import org.apache.zeppelin.resource.ResourcePool;
 import org.apache.zeppelin.resource.ResourceSet;
-import org.apache.zeppelin.util.ReflectionUtils;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -344,6 +345,21 @@ public class RemoteInterpreterEventServer implements 
RemoteInterpreterEventServi
     return obj;
   }
 
+  @Override
+  public List<ParagraphInfo> getParagraphList(String user, String noteId)
+      throws TException, ServiceException {
+    LOGGER.info("get paragraph list from remote interpreter noteId: " + noteId
+        + ", user = " + user);
+
+    if (user != null && noteId != null) {
+      List<ParagraphInfo> paragraphInfos = listener.getParagraphList(user, 
noteId);
+      return paragraphInfos;
+    } else {
+      LOGGER.error("user or noteId is null!");
+      return null;
+    }
+  }
+
   private Object invokeResourceMethod(String intpGroupId,
                                       final InvokeResourceMethodEventMessage 
message) {
     final ResourceId resourceId = message.resourceId;
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
index ac7fa1e..7584c42 100644
--- 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
+++ 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
@@ -16,7 +16,11 @@
  */
 package org.apache.zeppelin.interpreter.remote;
 
+import org.apache.thrift.TException;
 import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
+import org.apache.zeppelin.interpreter.thrift.ServiceException;
+import org.apache.zeppelin.user.AuthenticationInfo;
 
 import java.io.IOException;
 import java.util.List;
@@ -36,4 +40,6 @@ public interface RemoteInterpreterProcessListener {
 
   public void onParaInfosReceived(String noteId, String paragraphId,
                                   String interpreterSettingId, Map<String, 
String> metaInfos);
+
+  List<ParagraphInfo> getParagraphList(String user, String noteId) throws 
TException, ServiceException;
 }
diff --git 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
index 5e1cb7d..5a3e225 100644
--- 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
+++ 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
@@ -22,6 +22,8 @@ import org.apache.zeppelin.interpreter.InterpreterContext;
 import org.apache.zeppelin.interpreter.InterpreterException;
 import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -141,4 +143,9 @@ public class RemoteInterpreterOutputTestStream extends 
AbstractInterpreterTest
       String interpreterSettingId, Map<String, String> metaInfos) {
   }
 
+  @Override
+  public List<ParagraphInfo> getParagraphList(String user, String noteId) {
+    return null;
+  }
+
 }
diff --git 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
index 05f7bea..acba1c8 100644
--- 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
+++ 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
@@ -24,8 +24,10 @@ import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
+import org.apache.zeppelin.interpreter.thrift.ParagraphInfo;
 import org.apache.zeppelin.resource.LocalResourcePool;
 import org.apache.zeppelin.scheduler.Job.Status;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -287,4 +289,9 @@ public class RemoteSchedulerTest extends 
AbstractInterpreterTest
                                   String interpreterSettingId, Map<String, 
String> metaInfos) {
   }
 
+  @Override
+  public List<ParagraphInfo> getParagraphList(String user, String noteId) {
+    return null;
+  }
+
 }

Reply via email to