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 c277661 [ZEPPELIN-4912]. Angular object update in interpreter process side is not saved to note c277661 is described below commit c2776611152349299853c8a7918fa0e080fbccfd Author: Jeff Zhang <zjf...@apache.org> AuthorDate: Thu Jun 25 15:44:22 2020 +0800 [ZEPPELIN-4912]. Angular object update in interpreter process side is not saved to note ### What is this PR for? angularObject is saved in 2 places, one is in InterpreterGroup's `AngularObjectRegistry` another place is in `Note`. Unfortunately, we only saved it in `AngularObjectRegistry`, but not in Note. In this PR, we fix it in `RemoteInterpreterEventServer` which receive any update from interpreter process. ### What type of PR is it? [Bug Fix] ### Todos * [ ] - Task ### What is the Jira issue? * https://issues.apache.org/jira/browse/ZEPPELIN-4912 ### How should this be tested? * Unit test is added ### Screenshots (if appropriate) ### Questions: * Does the licenses files need update? No * Is there breaking changes for older versions? No * Does this needs documentation? No Author: Jeff Zhang <zjf...@apache.org> Closes #3830 from zjffdu/ZEPPELIN-4912 and squashes the following commits: f249c0bc5 [Jeff Zhang] [ZEPPELIN-4912]. Angular object update in interpreter process side is not saved to note --- .../integration/ZeppelinSparkClusterTest.java | 18 +++++++++++++++ .../org/apache/zeppelin/socket/NotebookServer.java | 2 +- .../interpreter/InterpreterSettingManager.java | 4 ++++ .../interpreter/RemoteInterpreterEventServer.java | 27 ++++++++++++++++++++++ .../java/org/apache/zeppelin/notebook/Note.java | 23 ++++++++++-------- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/zeppelin-interpreter-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinSparkClusterTest.java b/zeppelin-interpreter-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinSparkClusterTest.java index 21e626e..838d6f8 100644 --- a/zeppelin-interpreter-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinSparkClusterTest.java +++ b/zeppelin-interpreter-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinSparkClusterTest.java @@ -806,12 +806,19 @@ public abstract class ZeppelinSparkClusterTest extends AbstractTestRestApi { p1.setText("%spark z.angularBind(\"name\", \"world\")"); note.run(p1.getId(), true); assertEquals(Status.FINISHED, p1.getStatus()); + // angular object is saved to InterpreterGroup's AngularObjectRegistry List<AngularObject> angularObjects = p1.getBindedInterpreter().getInterpreterGroup() .getAngularObjectRegistry().getAll(note.getId(), null); assertEquals(1, angularObjects.size()); assertEquals("name", angularObjects.get(0).getName()); assertEquals("world", angularObjects.get(0).get()); + // angular object is saved to note as well. + angularObjects = note.getAngularObjects(p1.getBindedInterpreter().getInterpreterGroup().getId()); + assertEquals(1, angularObjects.size()); + assertEquals("name", angularObjects.get(0).getName()); + assertEquals("world", angularObjects.get(0).get()); + // remove local angular object Paragraph p2 = note.addNewParagraph(anonymous); p2.setText("%spark z.angularUnbind(\"name\")"); @@ -821,6 +828,9 @@ public abstract class ZeppelinSparkClusterTest extends AbstractTestRestApi { .getAll(note.getId(), null); assertEquals(0, angularObjects.size()); + angularObjects = note.getAngularObjects(p1.getBindedInterpreter().getInterpreterGroup().getId()); + assertEquals(0, angularObjects.size()); + // add global angular object Paragraph p3 = note.addNewParagraph(anonymous); p3.setText("%spark z.angularBindGlobal(\"name2\", \"world2\")"); @@ -832,6 +842,10 @@ public abstract class ZeppelinSparkClusterTest extends AbstractTestRestApi { assertEquals("name2", globalAngularObjects.get(0).getName()); assertEquals("world2", globalAngularObjects.get(0).get()); + // global angular object is not saved to note + angularObjects = note.getAngularObjects(p1.getBindedInterpreter().getInterpreterGroup().getId()); + assertEquals(0, angularObjects.size()); + // remove global angular object Paragraph p4 = note.addNewParagraph(anonymous); p4.setText("%spark z.angularUnbindGlobal(\"name2\")"); @@ -840,6 +854,10 @@ public abstract class ZeppelinSparkClusterTest extends AbstractTestRestApi { globalAngularObjects = p4.getBindedInterpreter().getInterpreterGroup() .getAngularObjectRegistry().getAll(note.getId(), null); assertEquals(0, globalAngularObjects.size()); + + // global angular object is not saved to note + angularObjects = note.getAngularObjects(p1.getBindedInterpreter().getInterpreterGroup().getId()); + assertEquals(0, angularObjects.size()); } finally { if (null != note) { TestUtils.getInstance(Notebook.class).removeNote(note, anonymous); 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 aefc61e..cf35d91 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 @@ -1370,7 +1370,7 @@ public class NotebookServer extends WebSocketServlet interpreterGroup.getAngularObjectRegistry(); AngularObject ao = removeAngularFromRemoteRegistry(noteId, paragraphId, varName, registry, interpreterGroup.getId(), conn); - note.deleteAngularObject(interpreterGroup.getId(), ao); + note.deleteAngularObject(interpreterGroup.getId(), noteId, paragraphId, varName); } } diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java index 558d4b1..4df049a 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java @@ -416,6 +416,10 @@ public class InterpreterSettingManager implements NoteEventListener, ClusterEven this.notebook = notebook; } + public Notebook getNotebook() { + return notebook; + } + public RemoteInterpreterProcessListener getRemoteInterpreterProcessListener() { return remoteInterpreterProcessListener; } 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 877d045..76f0f4f 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 @@ -44,6 +44,7 @@ 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.notebook.Note; import org.apache.zeppelin.resource.RemoteResource; import org.apache.zeppelin.resource.Resource; import org.apache.zeppelin.resource.ResourceId; @@ -252,6 +253,14 @@ public class RemoteInterpreterEventServer implements RemoteInterpreterEventServi } interpreterGroup.getAngularObjectRegistry().add(angularObject.getName(), angularObject.get(), angularObject.getNoteId(), angularObject.getParagraphId()); + if (angularObject.getNoteId() != null) { + try { + Note note = interpreterSettingManager.getNotebook().getNote(angularObject.getNoteId()); + note.addOrUpdateAngularObject(intpGroupId, angularObject); + } catch (IOException e) { + LOGGER.warn("Fail to get note: " + angularObject.getNoteId(), e); + } + } } @Override @@ -271,6 +280,15 @@ public class RemoteInterpreterEventServer implements RemoteInterpreterEventServi } else { localAngularObject.set(angularObject.get()); } + + if (angularObject.getNoteId() != null) { + try { + Note note = interpreterSettingManager.getNotebook().getNote(angularObject.getNoteId()); + note.addOrUpdateAngularObject(intpGroupId, angularObject); + } catch (IOException e) { + LOGGER.warn("Fail to get note: " + angularObject.getNoteId(), e); + } + } } @Override @@ -284,6 +302,15 @@ public class RemoteInterpreterEventServer implements RemoteInterpreterEventServi throw new TException("Invalid InterpreterGroupId: " + intpGroupId); } interpreterGroup.getAngularObjectRegistry().remove(name, noteId, paragraphId); + + if (noteId != null) { + try { + Note note = interpreterSettingManager.getNotebook().getNote(noteId); + note.deleteAngularObject(intpGroupId, noteId, paragraphId, name); + } catch (IOException e) { + LOGGER.warn("Fail to get note: " + noteId, e); + } + } } @Override 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 0e9fe89..882b368 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 @@ -394,7 +394,7 @@ public class Note implements JsonSerializable { /** * Delete the note AngularObject. */ - public void deleteAngularObject(String intpGroupId, AngularObject angularObject) { + public void deleteAngularObject(String intpGroupId, String noteId, String paragraphId, String name) { List<AngularObject> angularObjectList; if (!angularObjects.containsKey(intpGroupId)) { return; @@ -404,21 +404,26 @@ public class Note implements JsonSerializable { // Delete existing AngularObject Iterator<AngularObject> iter = angularObjectList.iterator(); while(iter.hasNext()){ - String noteId = "", paragraphId = ""; + String noteIdCandidate = ""; + String paragraphIdCandidate = ""; + String nameCandidate = ""; Object object = iter.next(); if (object instanceof AngularObject) { AngularObject ao = (AngularObject)object; - noteId = ao.getNoteId(); - paragraphId = ao.getParagraphId(); + noteIdCandidate = ao.getNoteId(); + paragraphIdCandidate = ao.getParagraphId(); + nameCandidate = ao.getName(); } else if (object instanceof RemoteAngularObject) { - RemoteAngularObject rao = (RemoteAngularObject)object; - noteId = rao.getNoteId(); - paragraphId = rao.getParagraphId(); + RemoteAngularObject rao = (RemoteAngularObject) object; + noteIdCandidate = rao.getNoteId(); + paragraphIdCandidate = rao.getParagraphId(); + nameCandidate = rao.getName(); } else { continue; } - if (StringUtils.equals(noteId, angularObject.getNoteId()) - && StringUtils.equals(paragraphId, angularObject.getParagraphId())) { + if (StringUtils.equals(noteId, noteIdCandidate) + && StringUtils.equals(paragraphId, paragraphIdCandidate) + && StringUtils.equals(name, nameCandidate)) { iter.remove(); } }