You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by pd...@apache.org on 2020/10/08 12:38:39 UTC

[zeppelin] branch branch-0.9 updated: [ZEPPELIN-5079] Rewrite communication with websequencediagrams in zeppelin-markdown

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

pdallig pushed a commit to branch branch-0.9
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/branch-0.9 by this push:
     new 6a5a431  [ZEPPELIN-5079] Rewrite communication with websequencediagrams in zeppelin-markdown
6a5a431 is described below

commit 6a5a4314a256129e14be7abc33bc0cf345df00a9
Author: Philipp Dallig <ph...@gmail.com>
AuthorDate: Thu Oct 1 12:16:52 2020 +0200

    [ZEPPELIN-5079] Rewrite communication with websequencediagrams in zeppelin-markdown
    
    ### What is this PR for?
    Includes:
     - Remove commons-io
     - Add org.apache.httpcomponents:httpclient to communicate with websequencediagrams.com
     - some small style changes
     - create MarkdownUtils to remove duplicate code
    
    ### What type of PR is it?
     - Improvement
    
    ### Todos
    * [ ] - Task
    
    ### What is the Jira issue?
    * https://issues.apache.org/jira/browse/ZEPPELIN-5079
    
    ### How should this be tested?
    * Travis-CI: https://travis-ci.org/github/Reamer/zeppelin/builds/733252017
    
    ### Questions:
    * Does the licenses files need update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    Author: Philipp Dallig <ph...@gmail.com>
    
    Closes #3931 from Reamer/markdown and squashes the following commits:
    
    ce8403787 [Philipp Dallig] create MarkdownUtils to remove duplicate code and rewrite connection to websequencediagrams.com
    6ba90dae3 [Philipp Dallig] style changes
    203cf4efe [Philipp Dallig] Update commons-io to parent version
    
    (cherry picked from commit 19dfc873af5cf74b715267a7640c7a9143240c38)
    Signed-off-by: Philipp Dallig <ph...@gmail.com>
---
 markdown/pom.xml                                   | 11 ++-
 .../org/apache/zeppelin/markdown/Markdown.java     |  2 +-
 .../apache/zeppelin/markdown/MarkdownUtils.java    | 81 ++++++++++++++++++++++
 .../org/apache/zeppelin/markdown/ParamVar.java     |  2 +-
 .../markdown/PegdownWebSequencelPlugin.java        | 67 +-----------------
 .../zeppelin/markdown/UMLBlockQuoteParser.java     |  4 +-
 .../apache/zeppelin/markdown/UMLNodeRenderer.java  | 70 +------------------
 .../zeppelin/markdown/FlexmarkParserTest.java      | 22 +++---
 .../zeppelin/markdown/PegdownParserTest.java       |  9 +--
 markdown/src/test/resources/log4j.properties       | 30 ++++++++
 10 files changed, 140 insertions(+), 158 deletions(-)

diff --git a/markdown/pom.xml b/markdown/pom.xml
index ceaa5c3..c393023 100644
--- a/markdown/pom.xml
+++ b/markdown/pom.xml
@@ -55,6 +55,11 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+    </dependency>
+
+    <dependency>
        <groupId>com.vladsch.flexmark</groupId>
        <artifactId>flexmark-all</artifactId>
        <version>${flexmark.all.version}</version>
@@ -72,12 +77,6 @@
       <artifactId>commons-lang3</artifactId>
     </dependency>
 
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>2.4</version>
-    </dependency>
-
   </dependencies>
 
   <build>
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java b/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
index 99aaac2..8e3ae25 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
@@ -76,7 +76,7 @@ public class Markdown extends Interpreter {
   }
 
   public static MarkdownParser createMarkdownParser(String parserType) {
-    LOGGER.debug("Creating " + parserType + " markdown interpreter");
+    LOGGER.debug("Creating {} markdown interpreter", parserType);
 
     if (MarkdownParserType.PEGDOWN.toString().equals(parserType)) {
       return new PegdownParser();
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/MarkdownUtils.java b/markdown/src/main/java/org/apache/zeppelin/markdown/MarkdownUtils.java
new file mode 100644
index 0000000..99915d6
--- /dev/null
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/MarkdownUtils.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zeppelin.markdown;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MarkdownUtils {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(MarkdownUtils.class);
+  public static final String WEBSEQ_URL = "https://www.websequencediagrams.com/";
+  public static final String WEBSEQ_URL_RENDER = "https://www.websequencediagrams.com/index.php";
+
+  private MarkdownUtils() {
+    throw new IllegalStateException("Utility class");
+  }
+
+  public static String createWebsequenceUrl(String style, String content) {
+    style = StringUtils.defaultString(style, "default").trim();
+
+    String webSeqUrl = "";
+
+    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+      HttpPost httpPost = new HttpPost(WEBSEQ_URL_RENDER);
+      ArrayList<NameValuePair> postParameters = new ArrayList<>();
+      postParameters.add(new BasicNameValuePair("style", style));
+      postParameters.add(new BasicNameValuePair("apiVersion", "1"));
+      postParameters.add(new BasicNameValuePair("format", "png"));
+      postParameters.add(new BasicNameValuePair("message", content));
+      httpPost.setEntity(new UrlEncodedFormEntity(postParameters, StandardCharsets.UTF_8));
+      try (CloseableHttpResponse post = httpClient.execute(httpPost)) {
+        if (post.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+          String postResponse = EntityUtils.toString(post.getEntity(), StandardCharsets.UTF_8);
+          int start = postResponse.indexOf("?png=");
+          int end = postResponse.indexOf("\"", start);
+
+          if (start != -1 && end != -1) {
+            webSeqUrl = WEBSEQ_URL + postResponse.substring(start, end);
+          } else {
+            LOGGER.error("Can't get imagecode");
+          }
+        } else {
+          LOGGER.error("websequencediagrams post failed with {}",
+              post.getStatusLine().getStatusCode());
+        }
+      }
+    } catch (IOException e) {
+      LOGGER.error("Communication with websequencediagrams broken", e);
+    }
+    return webSeqUrl;
+  }
+}
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java b/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java
index 14828e0..e8fc5ed 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java
@@ -31,7 +31,7 @@ import java.util.Map;
 public class ParamVar<K, V> extends Var<Map<K, V>> {
 
   public ParamVar() {
-    super(new HashMap<K, V>());
+    super(new HashMap<>());
   }
 
   public boolean put(K key, V value) {
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java b/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java
index 6238f95..47e3a23 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java
@@ -17,8 +17,6 @@
 
 package org.apache.zeppelin.markdown;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.parboiled.BaseParser;
 import org.parboiled.Rule;
 import org.parboiled.support.StringBuilderVar;
@@ -28,20 +26,10 @@ import org.pegdown.ast.TextNode;
 import org.pegdown.plugins.BlockPluginParser;
 import org.pegdown.plugins.PegDownPlugins;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-
 /**
  * Pegdown plugin for Websequence diagram.
  */
 public class PegdownWebSequencelPlugin extends Parser implements BlockPluginParser {
-  private static final String WEBSEQ_URL = "http://www.websequencediagrams.com";
 
   public PegdownWebSequencelPlugin() {
     super(PegdownParser.OPTIONS,
@@ -81,64 +69,11 @@ public class PegdownWebSequencelPlugin extends Parser implements BlockPluginPars
         endMarker(),
         push(
             new ExpImageNode("title",
-                createWebsequenceUrl(style.getString(), body.getString()),
+                MarkdownUtils.createWebsequenceUrl(style.getString(), body.getString()),
                 new TextNode("")))
     );
   }
 
-  public static String createWebsequenceUrl(String style, String content) {
-    style = StringUtils.defaultString(style, "default");
-
-    OutputStreamWriter writer = null;
-    BufferedReader reader = null;
-
-    String webSeqUrl = "";
-
-    try {
-      String query = new StringBuilder()
-          .append("style=")
-          .append(style)
-          .append("&message=")
-          .append(URLEncoder.encode(content, "UTF-8"))
-          .append("&apiVersion=1")
-          .toString();
-
-      URL url = new URL(WEBSEQ_URL);
-      URLConnection conn = url.openConnection();
-      conn.setDoOutput(true);
-      writer = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
-      writer.write(query);
-      writer.flush();
-
-      StringBuilder response = new StringBuilder();
-      reader = new BufferedReader(
-          new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
-      String line;
-      while ((line = reader.readLine()) != null) {
-        response.append(line);
-      }
-
-      writer.close();
-      reader.close();
-
-      String json = response.toString();
-
-      int start = json.indexOf("?png=");
-      int end = json.indexOf("\"", start);
-
-      if (start != -1 && end != -1) {
-        webSeqUrl = WEBSEQ_URL + "/" + json.substring(start, end);
-      }
-    } catch (IOException e) {
-      throw new RuntimeException("Failed to get proper response from websequencediagrams.com", e);
-    } finally {
-      IOUtils.closeQuietly(writer);
-      IOUtils.closeQuietly(reader);
-    }
-
-    return webSeqUrl;
-  }
-
   @Override
   public Rule[] blockPluginRules() {
     return new Rule[]{blockRule()};
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/UMLBlockQuoteParser.java b/markdown/src/main/java/org/apache/zeppelin/markdown/UMLBlockQuoteParser.java
index 9d56856..92a12ba 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/UMLBlockQuoteParser.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/UMLBlockQuoteParser.java
@@ -49,8 +49,8 @@ public class UMLBlockQuoteParser extends AbstractBlockParser {
   private static final Logger LOGGER = LoggerFactory.getLogger(UMLBlockQuoteParser.class);
 
 
-  private static Pattern YUML_BLOCK_START = Pattern.compile("(%%%)\\s+(.*\\n)");
-  private static Pattern YUML_BLOCK_END = Pattern.compile("%%%(\\s*$)");
+  private static final Pattern YUML_BLOCK_START = Pattern.compile("(%%%)\\s+(.*\\n)");
+  private static final Pattern YUML_BLOCK_END = Pattern.compile("%%%(\\s*$)");
 
   private final UMLBlockQuote block = new UMLBlockQuote();
   private BlockContent content = new BlockContent();
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/UMLNodeRenderer.java b/markdown/src/main/java/org/apache/zeppelin/markdown/UMLNodeRenderer.java
index 39406f9..b2cc8dc 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/UMLNodeRenderer.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/UMLNodeRenderer.java
@@ -26,21 +26,11 @@ import com.vladsch.flexmark.html.renderer.NodeRendererContext;
 import com.vladsch.flexmark.html.renderer.NodeRenderingHandler;
 import com.vladsch.flexmark.util.data.DataHolder;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLConnection;
 import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-
 import java.util.Map;
 import java.util.Set;
 import java.util.HashSet;
@@ -58,7 +48,6 @@ public class UMLNodeRenderer implements NodeRenderer {
 
   public static final String YUML = "yuml";
   public static final String SEQUENCE = "sequence";
-  public static final String WEBSEQ_URL = "http://www.websequencediagrams.com";
 
   final GitLabOptions options;
 
@@ -103,7 +92,8 @@ public class UMLNodeRenderer implements NodeRenderer {
       url = createYumlUrl(paramMap, node.getFirstChild().getChars().toString());
       LOGGER.debug("Encoded YUML URL {} ", url);
     } else if (splitWithSpace[0].equals(SEQUENCE) && !Objects.isNull(node.getFirstChild())) {
-      url = createWebsequenceUrl(paramMap.get("style"), node.getFirstChild().getChars().toString());
+      url = MarkdownUtils.createWebsequenceUrl(paramMap.get("style"),
+                                               node.getFirstChild().getChars().toString());
       LOGGER.debug("Encoded web sequence diagram URL {} ", url);
     } else {
       html.withAttr().tagLineIndent("blockquote", new Runnable() {
@@ -172,60 +162,4 @@ public class UMLNodeRenderer implements NodeRenderer {
         .append("." + format)
         .toString();
   }
-
-  public static String createWebsequenceUrl(String style,
-                                            String content) {
-
-    style = StringUtils.defaultString(style, "default");
-
-    OutputStreamWriter writer = null;
-    BufferedReader reader = null;
-
-    String webSeqUrl = "";
-
-    try {
-      String query = new StringBuilder()
-          .append("style=")
-          .append(style)
-          .append("&message=")
-          .append(URLEncoder.encode(content, "UTF-8"))
-          .append("&apiVersion=1")
-          .toString();
-
-      URL url = new URL(WEBSEQ_URL);
-      URLConnection conn = url.openConnection();
-      conn.setDoOutput(true);
-      writer = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
-      writer.write(query);
-      writer.flush();
-
-      StringBuilder response = new StringBuilder();
-      reader = new BufferedReader(
-          new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
-      String line;
-      while ((line = reader.readLine()) != null) {
-        response.append(line);
-      }
-
-      writer.close();
-      reader.close();
-
-      String json = response.toString();
-
-      int start = json.indexOf("?png=");
-      int end = json.indexOf("\"", start);
-
-      if (start != -1 && end != -1) {
-        webSeqUrl = WEBSEQ_URL + "/" + json.substring(start, end);
-        System.out.println("websequrl : " + webSeqUrl);
-      }
-    } catch (IOException e) {
-      throw new RuntimeException("Failed to get proper response from websequencediagrams.com", e);
-    } finally {
-      IOUtils.closeQuietly(writer);
-      IOUtils.closeQuietly(reader);
-    }
-
-    return webSeqUrl;
-  }
 }
diff --git a/markdown/src/test/java/org/apache/zeppelin/markdown/FlexmarkParserTest.java b/markdown/src/test/java/org/apache/zeppelin/markdown/FlexmarkParserTest.java
index a80337e..7b60613 100644
--- a/markdown/src/test/java/org/apache/zeppelin/markdown/FlexmarkParserTest.java
+++ b/markdown/src/test/java/org/apache/zeppelin/markdown/FlexmarkParserTest.java
@@ -36,7 +36,7 @@ import static org.junit.Assert.assertThat;
 
 public class FlexmarkParserTest {
 
-  Logger logger = LoggerFactory.getLogger(FlexmarkParserTest.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(FlexmarkParserTest.class);
   Markdown md;
 
   @Rule
@@ -60,12 +60,13 @@ public class FlexmarkParserTest {
     ArrayList<Thread> arrThreads = new ArrayList<Thread>();
     for (int i = 0; i < 10; i++) {
       Thread t = new Thread() {
+        @Override
         public void run() {
           String r1 = null;
           try {
             r1 = md.interpret("# H1", null).code().name();
           } catch (Exception e) {
-            logger.error("testTestMultipleThread failed to interpret", e);
+            LOGGER.error("testTestMultipleThread failed to interpret", e);
           }
           collector.checkThat("SUCCESS",
               CoreMatchers.containsString(r1));
@@ -79,7 +80,7 @@ public class FlexmarkParserTest {
       try {
         arrThreads.get(i).join();
       } catch (InterruptedException e) {
-        logger.error("testTestMultipleThread failed to join threads", e);
+        LOGGER.error("testTestMultipleThread failed to join threads", e);
       }
     }
   }
@@ -212,14 +213,15 @@ public class FlexmarkParserTest {
             .toString();
 
     InterpreterResult result = md.interpret(input, null);
-    
-    System.err.println(result.message().get(0).getData());
-    if (!result.message().get(0).getData().contains(
-        "<img src=\"http://www.websequencediagrams.com/?png=")) {
-      logger.error("Expected {} but found {}",
-          "<img src=\"http://www.websequencediagrams.com/?png=", result.message().get(0).getData());
+
+    final String expected = "<img src=\"https://www.websequencediagrams.com/?png=";
+    boolean containsImg = result.message().get(0).getData().contains(expected);
+    if (!containsImg) {
+      LOGGER.error("Expected {} but found {}",
+          expected, result.message().get(0).getData());
     }
+    // Do not activate, because this test depends on www.websequencediagrams.com
+    //assertTrue(containsImg);
   }
-
 }
 
diff --git a/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java b/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java
index a608a05..ec12bb8 100644
--- a/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java
+++ b/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java
@@ -37,7 +37,7 @@ import java.util.Properties;
 import org.apache.zeppelin.interpreter.InterpreterResult;
 
 public class PegdownParserTest {
-  Logger logger = LoggerFactory.getLogger(PegdownParserTest.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(PegdownParserTest.class);
   Markdown md;
 
   @Rule
@@ -61,12 +61,13 @@ public class PegdownParserTest {
     ArrayList<Thread> arrThreads = new ArrayList<>();
     for (int i = 0; i < 10; i++) {
       Thread t = new Thread() {
+        @Override
         public void run() {
           String r1 = null;
           try {
             r1 = md.interpret("# H1", null).code().name();
           } catch (Exception e) {
-            logger.error("testTestMultipleThread failed to interpret", e);
+            LOGGER.error("testTestMultipleThread failed to interpret", e);
           }
           collector.checkThat("SUCCESS",
               CoreMatchers.containsString(r1));
@@ -80,7 +81,7 @@ public class PegdownParserTest {
       try {
         arrThreads.get(i).join();
       } catch (InterruptedException e) {
-        logger.error("testTestMultipleThread failed to join threads", e);
+        LOGGER.error("testTestMultipleThread failed to join threads", e);
       }
     }
   }
@@ -381,7 +382,7 @@ public class PegdownParserTest {
     System.err.println(result.message().get(0).getData());
     if (!result.message().get(0).getData().contains(
         "<img src=\"http://www.websequencediagrams.com/?png=")) {
-      logger.error("Expected {} but found {}",
+      LOGGER.error("Expected {} but found {}",
           "<img src=\"http://www.websequencediagrams.com/?png=", result.message().get(0).getData());
     }
   }
diff --git a/markdown/src/test/resources/log4j.properties b/markdown/src/test/resources/log4j.properties
new file mode 100644
index 0000000..b724845
--- /dev/null
+++ b/markdown/src/test/resources/log4j.properties
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n
+#log4j.appender.stdout.layout.ConversionPattern=
+#%5p [%t] (%F:%L) - %m%n
+#%-4r [%t] %-5p %c %x - %m%n
+#
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+#log4j.logger.org.apache.zeppelin.interpreter=DEBUG