You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2019/01/29 03:12:18 UTC

[zeppelin] branch master updated: [ZEPPELIN-3920] Paragraph support custom menu display with multiple URL link

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 1979a0a  [ZEPPELIN-3920] Paragraph support custom menu display with multiple URL link
1979a0a is described below

commit 1979a0ac3a4b6e2b1c999f97796d8e59c62a047f
Author: liuxunorg <33...@qq.com>
AuthorDate: Mon Jan 28 19:41:34 2019 +0800

    [ZEPPELIN-3920] Paragraph support custom menu display with multiple URL link
    
    ### What is this PR for?
    
    Now the execution of the paragraph in zeppelin only supports the display of a single URL link, for example: Spark paragraph execution is a Spark JOB URL link.
    The machine learning task in the hadoop submarine needs to provide the user with a tensorflow Parameter server, a tensorflow worker server log link in YARN, and a tensorboard link, so a custom menu display that supports multiple URL links is now available.
    
    ### What type of PR is it?
    [Improvement]
    
    ### Todos
    * [x] Add testRuntimeInfos test cases in NotebookServerTest.java
    * [x] modify paragraph-control.html
    
    ### What is the Jira issue?
    * https://issues.apache.org/jira/browse/ZEPPELIN-3920
    
    ### How should this be tested?
    [CI pass](https://travis-ci.org/liuxunorg/zeppelin/builds/472116016)
    
    ### Screenshots (if appropriate)
    
    ![alt text](https://github.com/liuxunorg/images/blob/master/zeppelin/multi-job-url.gif?raw=true "multi-job-url.gif")
    
    ### Questions:
    * Does the licenses files need update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    Author: liuxunorg <33...@qq.com>
    
    Closes #3273 from liuxunorg/ZEPPELIN-3920 and squashes the following commits:
    
    2c7e4bfe5 [liuxunorg] Fix single URL menu bug.
    949ead1c6 [liuxunorg] [ZEPPELIN-3920] Paragraph support custom menu display with multiple URL links
---
 .../apache/zeppelin/socket/NotebookServerTest.java | 49 ++++++++++++++++++++++
 .../app/notebook/paragraph/paragraph-control.html  | 23 +++-------
 .../org/apache/zeppelin/notebook/Paragraph.java    |  2 +-
 .../zeppelin/notebook/ParagraphRuntimeInfo.java    | 18 ++++++--
 4 files changed, 69 insertions(+), 23 deletions(-)

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 ab805b8..08bed2f 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
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.List;
+import java.util.Map;
 import javax.inject.Provider;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
@@ -419,6 +420,54 @@ public class NotebookServerTest extends AbstractTestRestApi {
     notebook.removeNote(createdNote.getId(), anonymous);
   }
 
+  @Test
+  public void testRuntimeInfos() {
+    // mock note
+    String msg = "{\"op\":\"IMPORT_NOTE\",\"data\":" +
+        "{\"note\":{\"paragraphs\": [{\"text\": \"Test " +
+        "paragraphs import\"," + "\"progressUpdateIntervalMs\":500," +
+        "\"config\":{},\"settings\":{}}]," +
+        "\"name\": \"Test Zeppelin notebook import\",\"config\": " +
+        "{}}}}";
+    Message messageReceived = notebookServer.deserializeMessage(msg);
+    Note note = null;
+    try {
+      note = notebookServer.importNote(null, messageReceived);
+    } catch (NullPointerException e) {
+      //broadcastNoteList(); failed nothing to worry.
+      LOG.error("Exception in NotebookServerTest while testImportNotebook, failed nothing to " +
+          "worry ", e);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    assertNotEquals(null, notebook.getNote(note.getId()));
+    assertNotEquals(null, note.getParagraph(0));
+
+    String nodeId = note.getId();
+    String paragraphId = note.getParagraph(0).getId();
+
+    // update RuntimeInfos
+    Map<String, String> infos = new java.util.HashMap<>();
+    infos.put("jobUrl", "jobUrl_value");
+    infos.put("jobLabel", "jobLabel_value");
+    infos.put("label", "SPARK JOB");
+    infos.put("tooltip", "View in Spark web UI");
+    infos.put("noteId", nodeId);
+    infos.put("paraId", paragraphId);
+
+    notebookServer.onParaInfosReceived(nodeId, paragraphId, "spark", infos);
+    Paragraph paragraph = note.getParagraph(paragraphId);
+
+    // check RuntimeInfos
+    assertTrue(paragraph.getRuntimeInfos().containsKey("jobUrl"));
+    List<Map<String, String>> list = paragraph.getRuntimeInfos().get("jobUrl").getValue();
+    assertEquals(1, list.size());
+    assertEquals(2, list.get(0).size());
+    assertEquals(list.get(0).get("jobUrl"), "jobUrl_value");
+    assertEquals(list.get(0).get("jobLabel"), "jobLabel_value");
+  }
+
   private NotebookSocket createWebSocket() {
     NotebookSocket sock = mock(NotebookSocket.class);
     when(sock.getRequest()).thenReturn(mockRequest);
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
index 4ef430f..b39ac08 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
@@ -15,7 +15,7 @@ limitations under the License.
 <div id="{{paragraph.id}}_control" class="control" ng-show="!asIframe">
   <span>
     <span ng-show="paragraph.runtimeInfos.jobUrl.values.length == 1">
-      <a href="{{paragraph.runtimeInfos.jobUrl.values[0]}}" target="_blank" style="text-decoration: none;"
+      <a href="{{paragraph.runtimeInfos.jobUrl.jobUrl}}" target="_blank" style="text-decoration: none;"
          tooltip-placement="top" uib-tooltip="{{paragraph.runtimeInfos.jobUrl.tooltip}}" >
         <span class="fa fa-tasks"></span>
         {{paragraph.runtimeInfos.jobUrl.label}}
@@ -25,11 +25,12 @@ limitations under the License.
       <span style="cursor:pointer;color:#3071A9" tooltip-placement="top" uib-tooltip="{{paragraph.runtimeInfos.jobUrl.tooltip}}"
             data-toggle="dropdown" type="button">
         <span class="fa fa-tasks"></span>
-        {{paragraph.runtimeInfos.jobUrl.label}}S
+        {{paragraph.runtimeInfos.jobUrl.label}}
       </span>
       <ul class="dropdown-menu" role="menu" style="width:200px;z-index:1002">
-        <li ng-class="{'option-disabled': !noteOperationsAllowed()}" ng-repeat="url in paragraph.runtimeInfos.jobUrl.values">
-          <a href="{{url}}" target="_blank"><span class="fa fa-external-link-square"></span> Jobs #{{$index}}</a>
+        <li ng-class="{'option-disabled': !noteOperationsAllowed()}" ng-repeat="value in paragraph.runtimeInfos.jobUrl.values">
+          <a ng-if="value.jobLabel === undefined" href="{{value['jobUrl']}}" target="_blank"><span class="fa fa-external-link-square"></span> Jobs #{{$index}}</a>
+          <a ng-if="value.jobLabel !== undefined" href="{{value['jobUrl']}}" target="_blank"><span class="fa fa-external-link-square"></span> {{value['jobLabel']}} </a>
         </li>
       </ul>
     </span>
@@ -54,20 +55,6 @@ limitations under the License.
           ng-click="cancelParagraph(paragraph)"
           ng-class="{'item-disable' : isNoteRunning}"
           ng-show="paragraph.status=='RUNNING' || paragraph.status=='PENDING'"></span>
-    <span ng-show="paragraph.runtimeInfos.jobUrl.length == 1">
-      <a href="{{paragraph.runtimeInfos.jobUrl[0]}}" target="_blank"><span class="fa fa-tasks"></span> Spark job </a>
-    </span>
-    <span class="dropdown" ng-show="paragraph.runtimeInfos.jobUrl.length > 1">
-      <span class="fa fa-tasks" style="cursor:pointer;color:#3071A9" tooltip-placement="top" uib-tooltip="Run this paragraph (Shift+Enter)"
-          data-toggle="dropdown"
-          type="button">  Spark Jobs
-      </span>
-      <ul class="dropdown-menu" role="menu" style="width:200px;z-index:1002">
-         <li ng-class="{'option-disabled': !noteOperationsAllowed()}" ng-repeat="url in paragraph.runtimeInfos.jobUrl">
-           <a href="{{url}}" target="_blank"><span class="fa fa-external-link-square"></span> Jobs #{{$index}}</a>
-         </li>
-      </ul>
-    </span>
     <span class="{{paragraph.config.editorHide ? 'icon-size-fullscreen' : 'icon-size-actual'}}" style="cursor:pointer" tooltip-placement="top"
           uib-tooltip="{{(paragraph.config.editorHide ? 'Show' : 'Hide')}} editor (Ctrl+{{ (isMac ? 'Option' : 'Alt') }}+E)"
           ng-click="toggleEditor(paragraph)"></span>
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
index bd3104f..ce78230 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
@@ -655,7 +655,7 @@ public class Paragraph extends JobWithProgressPoller<InterpreterResult> implemen
           info = new ParagraphRuntimeInfo(key, label, tooltip, group, intpSettingId);
           this.runtimeInfos.put(key, info);
         }
-        info.addValue(infos.get(key));
+        info.addValue(infos);
       }
     }
   }
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/ParagraphRuntimeInfo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/ParagraphRuntimeInfo.java
index 0042023..23ce9e8 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/ParagraphRuntimeInfo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/ParagraphRuntimeInfo.java
@@ -1,19 +1,24 @@
 package org.apache.zeppelin.notebook;
 
+import com.google.common.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Store runtime infos of each para
  *
  */
 public class ParagraphRuntimeInfo {
-
   private String propertyName;  // Name of the property
   private String label;         // Label to be used in UI
   private String tooltip;       // Tooltip text toshow in UI
   private String group;         // The interpretergroup from which the info was derived
-  private List<String> values;  // values for the property
+
+  // runtimeInfos job url or dropdown-menu key in
+  // zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
+  private List<Map<String, String>> values;  // values for the key-value pair property
   private String interpreterSettingId;
   
   public ParagraphRuntimeInfo(String propertyName, String label, 
@@ -29,8 +34,13 @@ public class ParagraphRuntimeInfo {
     this.values = new ArrayList<>();
   }
 
-  public void addValue(String value) {
-    values.add(value);
+  public void addValue(Map<String, String> mapValue) {
+    values.add(mapValue);
+  }
+
+  @VisibleForTesting
+  public List<Map<String, String>> getValue() {
+    return values;
   }
   
   public String getInterpreterSettingId() {