You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ke...@apache.org on 2021/11/03 10:46:31 UTC

[dolphinscheduler] branch dev updated: [Fix][Standalone Server] fix plugin load failed when local maven repository path is not default value (#6625) (#6626)

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

kerwin pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 61a8726  [Fix][Standalone Server] fix plugin load failed when local maven repository path is not default value (#6625) (#6626)
61a8726 is described below

commit 61a8726ccc42a2adba8cdc859e3c3271099fdade
Author: LiuBodong <li...@126.com>
AuthorDate: Wed Nov 3 18:46:25 2021 +0800

    [Fix][Standalone Server] fix plugin load failed when local maven repository path is not default value (#6625) (#6626)
    
    * [Fix][Standalone Server] fix plugin load failed when local maven repository path is not default value
---
 .../spi/plugin/DolphinPluginManagerConfig.java     | 124 ++++++++++++++++++++-
 1 file changed, 123 insertions(+), 1 deletion(-)

diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/plugin/DolphinPluginManagerConfig.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/plugin/DolphinPluginManagerConfig.java
index 518f90e..871fe66 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/plugin/DolphinPluginManagerConfig.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/plugin/DolphinPluginManagerConfig.java
@@ -20,9 +20,24 @@ package org.apache.dolphinscheduler.spi.plugin;
 import static java.lang.String.format;
 import static java.util.Objects.requireNonNull;
 
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.List;
 
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 
@@ -31,6 +46,8 @@ import com.google.common.collect.ImmutableList;
  */
 public class DolphinPluginManagerConfig {
 
+    private static final Logger logger = LoggerFactory.getLogger(DolphinPluginManagerConfig.class);
+
     /**
      * The dir of the Alert Plugin in.
      * When AlertServer is running on the server, it will load the Alert Plugin from this directory.
@@ -46,7 +63,8 @@ public class DolphinPluginManagerConfig {
     /**
      * Development, When AlertServer is running on IDE, AlertPluginLoad can load Alert Plugin from local Repository.
      */
-    private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+    private final String defaultLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+    private String mavenLocalRepository = getMavenLocalRepositoryOrDefault(defaultLocalRepository);
     private List<String> mavenRemoteRepository = ImmutableList.of("http://repo1.maven.org/maven2/");
 
     File getInstalledPluginsDir() {
@@ -107,6 +125,110 @@ public class DolphinPluginManagerConfig {
         return mavenRemoteRepository;
     }
 
+    /**
+     * Get local repository from maven settings.xml if available.
+     * <p>
+     * if System environment does not exists settings.xml, return the default value.
+     * </p>
+     *
+     * @param defaultRepository default repository path.
+     * @return local repository path.
+     */
+    private String getMavenLocalRepositoryOrDefault(String defaultRepository) {
+        // get 'settings.xml' from user home
+        Path settingsXmlPath = getMavenSettingsXmlFromUserHome();
+        // if user home does not exist settings.xml, get from '$MAVEN_HOME/conf/settings.xml'
+        if (settingsXmlPath == null) {
+            logger.info("User home does not exists maven settings.xml");
+            settingsXmlPath = getMavenSettingsXmlFromEvn();
+        }
+        // still not exist, return default repository
+        if (settingsXmlPath == null) {
+            logger.info("Maven home does not exists maven settings.xml, use default");
+            return defaultRepository;
+        }
+        // parse xml
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder;
+        try {
+            // security settings
+            try {
+                factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+                factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+                factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+                factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+                factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+            } catch (Exception e) {
+                logger.warn("Error at parse settings.xml, setting security features: {}", e.getLocalizedMessage());
+            }
+            documentBuilder = factory.newDocumentBuilder();
+            Document document = documentBuilder.parse(settingsXmlPath.toFile());
+            // search node named 'localRepository'
+            String localRepositoryNodeTag = "localRepository";
+            NodeList nodeList = document.getElementsByTagName(localRepositoryNodeTag);
+            int length = nodeList.getLength();
+            if (length <= 0) {
+                // if node not exists, return default repository
+                logger.info("File {} does not contains node named {}", settingsXmlPath, localRepositoryNodeTag);
+                return defaultRepository;
+            }
+            for (int i = 0; i < length; i++) {
+                Node node = nodeList.item(i);
+                String content = node.getTextContent();
+                if (StringUtils.isNotEmpty(content) && StringUtils.isNotBlank(content)) {
+                    Path localRepositoryPath = Paths.get(content);
+                    if (Files.exists(localRepositoryPath)) {
+                        logger.info("Got local repository path {}", content);
+                        return content;
+                    }
+                }
+            }
+            return defaultRepository;
+        } catch (Exception e) {
+            logger.error(e.getLocalizedMessage(), e);
+            return defaultRepository;
+        }
+    }
+
+    /**
+     * Get maven settings.xml file path from "${user.home}/.m2"
+     * <p>
+     * if "${user.home}/.m2/settings.xml" does not exist,
+     * null will be returned
+     * </p>
+     *
+     * @return settings.xml file path, could be null
+     */
+    private Path getMavenSettingsXmlFromUserHome() {
+        String userHome = System.getProperty("user.home");
+        Path settingsXmlPath = null;
+        if (!StringUtils.isEmpty(userHome)) {
+            settingsXmlPath = Paths.get(userHome, ".m2", "settings.xml").toAbsolutePath();
+        }
+        return settingsXmlPath;
+    }
+
+    /**
+     * Get maven settings.xml file path from "${MAVEN_HOME}/conf"
+     * <p>
+     * if "${MAVEN_HOME}/conf/settings.xml" does not exist,
+     * null will be returned
+     * </p>
+     *
+     * @return settings.xml file path, could be null
+     */
+    private Path getMavenSettingsXmlFromEvn() {
+        String mavenHome = System.getenv("MAVEN_HOME");
+        Path settingsXmlPath = null;
+        if (mavenHome == null) {
+            mavenHome = System.getenv("M2_HOME");
+        }
+        if (mavenHome != null) {
+            settingsXmlPath = Paths.get(mavenHome, "conf", "settings.xml").toAbsolutePath();
+        }
+        return settingsXmlPath;
+    }
+
     public DolphinPluginManagerConfig setMavenRemoteRepository(List<String> mavenRemoteRepository) {
         this.mavenRemoteRepository = mavenRemoteRepository;
         return this;