Repository: zeppelin Updated Branches: refs/heads/master c3fbb1ef6 -> 4b1b521fc
[ZEPPELIN-2179] Clear output DOES NOT work in personalized mode (master) ### What is this PR for? `clear output` (`cmd` + `opt` + `L`) doesn't work in the personalized mode. ### What type of PR is it? [Bug Fix] ### Todos NONE ### What is the Jira issue? [ZEPPELIN-2179](https://issues.apache.org/jira/browse/ZEPPELIN-2179) ### How should this be tested? 1. Configure shiro 2. Start Zeppelin and login in 2 browsers (e.g chrome and safari) with 2 different users (**DO NOT USE `dev` mode: localhost:9000**) 3. Create a note 4. Enable personalized mode 5. Run paragraph and clear output in each browser ### Screenshots (if appropriate) NONE ### Questions: * Does the licenses files need update? - NO * Is there breaking changes for older versions? - NO * Does this needs documentation? - NO Author: 1ambda <1am...@gmail.com> Closes #2253 from 1ambda/ZEPPELIN-2179/clear-output-doesnt-work-in-person-mode-for-master and squashes the following commits: eeff440ec [1ambda] fix: Clear personalized output before running b7387849f [1ambda] fix: Clear output in personalized paragraph Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/4b1b521f Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/4b1b521f Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/4b1b521f Branch: refs/heads/master Commit: 4b1b521fc34fd3c841e38ab591af0bc7df21a64e Parents: c3fbb1e Author: 1ambda <1am...@gmail.com> Authored: Sat Apr 15 17:18:56 2017 +0900 Committer: Jongyoul Lee <jongy...@apache.org> Committed: Thu Apr 20 01:40:01 2017 +0900 ---------------------------------------------------------------------- .../apache/zeppelin/socket/NotebookServer.java | 39 ++++++++++++++++++-- .../java/org/apache/zeppelin/notebook/Note.java | 29 +++++++++++++-- 2 files changed, 60 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4b1b521f/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java index 87a6bca..1aa4f28 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 @@ -644,6 +644,22 @@ public class NotebookServer extends WebSocketServlet broadcast(noteId, new Message(OP.INTERPRETER_BINDINGS).put("interpreterBindings", settingList)); } + public void unicastParagraph(Note note, Paragraph p, String user) { + if (!note.isPersonalizedMode() || p == null || user == null) { + return; + } + + if (!userConnectedSockets.containsKey(user)) { + LOG.warn("Failed to send unicast. user {} that is not in connections map", user); + return; + } + + for (NotebookSocket conn : userConnectedSockets.get(user)) { + Message m = new Message(OP.PARAGRAPH).put("paragraph", p); + unicast(m, conn); + } + } + public void broadcastParagraph(Note note, Paragraph p) { if (note.isPersonalizedMode()) { broadcastParagraphs(p.getUserParagraphMap(), p); @@ -1301,9 +1317,15 @@ public class NotebookServer extends WebSocketServlet } final Note note = notebook.getNote(noteId); - note.clearParagraphOutput(paragraphId); - Paragraph paragraph = note.getParagraph(paragraphId); - broadcastParagraph(note, paragraph); + if (note.isPersonalizedMode()) { + String user = fromMessage.principal; + Paragraph p = note.clearPersonalizedParagraphOutput(paragraphId, user); + unicastParagraph(note, p, user); + } else { + note.clearParagraphOutput(paragraphId); + Paragraph paragraph = note.getParagraph(paragraphId); + broadcastParagraph(note, paragraph); + } } private void completion(NotebookSocket conn, HashSet<String> userAndRoles, Notebook notebook, @@ -1696,12 +1718,21 @@ public class NotebookServer extends WebSocketServlet return; } + // 1. clear paragraph only if personalized, + // otherwise this will be handed in `onOutputClear` + final Note note = notebook.getNote(noteId); + if (note.isPersonalizedMode()) { + String user = fromMessage.principal; + Paragraph p = note.clearPersonalizedParagraphOutput(paragraphId, user); + unicastParagraph(note, p, user); + } + + // 2. set paragraph values String text = (String) fromMessage.get("paragraph"); String title = (String) fromMessage.get("title"); Map<String, Object> params = (Map<String, Object>) fromMessage.get("params"); Map<String, Object> config = (Map<String, Object>) fromMessage.get("config"); - final Note note = notebook.getNote(noteId); Paragraph p = setParagraphUsingMessage(note, fromMessage, paragraphId, text, title, params, config); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4b1b521f/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java index dd2c094..3e6ab23 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java @@ -390,6 +390,26 @@ public class Note implements Serializable, ParagraphJobListener { return null; } + public void clearParagraphOutputFields(Paragraph p) { + p.setReturn(null, null); + p.clearRuntimeInfo(null); + } + + public Paragraph clearPersonalizedParagraphOutput(String paragraphId, String user) { + synchronized (paragraphs) { + for (Paragraph p : paragraphs) { + if (!p.getId().equals(paragraphId)) { + continue; + } + + p = p.getUserParagraphMap().get(user); + clearParagraphOutputFields(p); + return p; + } + } + return null; + } + /** * Clear paragraph output by id. * @@ -399,11 +419,12 @@ public class Note implements Serializable, ParagraphJobListener { public Paragraph clearParagraphOutput(String paragraphId) { synchronized (paragraphs) { for (Paragraph p : paragraphs) { - if (p.getId().equals(paragraphId)) { - p.setReturn(null, null); - p.clearRuntimeInfo(null); - return p; + if (!p.getId().equals(paragraphId)) { + continue; } + + clearParagraphOutputFields(p); + return p; } } return null;