From 61a8726ccc42a2adba8cdc859e3c3271099fdade Mon Sep 17 00:00:00 2001 From: LiuBodong Date: Wed, 3 Nov 2021 18:46:25 +0800 Subject: [PATCH] [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 --- .../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 518f90e810..871fe66868 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 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. + *

+ * if System environment does not exists settings.xml, return the default value. + *

+ * + * @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" + *

+ * if "${user.home}/.m2/settings.xml" does not exist, + * null will be returned + *

+ * + * @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" + *

+ * if "${MAVEN_HOME}/conf/settings.xml" does not exist, + * null will be returned + *

+ * + * @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 mavenRemoteRepository) { this.mavenRemoteRepository = mavenRemoteRepository; return this;