diff --git a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/ErrorException.java b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/ErrorException.java index fc361ee860..d7ea54d268 100644 --- a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/ErrorException.java +++ b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/ErrorException.java @@ -17,7 +17,7 @@ package org.apache.linkis.common.exception; -public class ErrorException extends LinkisException { +public class ErrorException extends LinkisRuntimeException { private ExceptionLevel level = ExceptionLevel.ERROR; public ErrorException(int errCode, String desc) { diff --git a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/FatalException.java b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/FatalException.java index 26a6992c05..4847d76d63 100644 --- a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/FatalException.java +++ b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/FatalException.java @@ -17,7 +17,7 @@ package org.apache.linkis.common.exception; -public class FatalException extends LinkisException { +public class FatalException extends LinkisRuntimeException { private ExceptionLevel level = ExceptionLevel.FATAL; public FatalException(int errCode, String desc) { diff --git a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/LinkisRetryException.java b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/LinkisRetryException.java index b9efe6cdf9..01a95db0f3 100644 --- a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/LinkisRetryException.java +++ b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/exception/LinkisRetryException.java @@ -17,7 +17,7 @@ package org.apache.linkis.common.exception; -public class LinkisRetryException extends LinkisException { +public class LinkisRetryException extends LinkisRuntimeException { LinkisRetryException(int errCode, String desc, String ip, int port, String serviceKind) { super(errCode, desc, ip, port, serviceKind); } @@ -27,7 +27,7 @@ public LinkisRetryException(int errCode, String desc) { } @Override - ExceptionLevel getLevel() { + public ExceptionLevel getLevel() { return ExceptionLevel.RETRY; } } diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/java/org/apache/linkis/governance/common/utils/ECPathUtils.java b/linkis-computation-governance/linkis-computation-governance-common/src/main/java/org/apache/linkis/governance/common/utils/ECPathUtils.java new file mode 100644 index 0000000000..739c256af1 --- /dev/null +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/java/org/apache/linkis/governance/common/utils/ECPathUtils.java @@ -0,0 +1,53 @@ +/* + * 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.linkis.governance.common.utils; + +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.manager.label.entity.engine.UserCreatorLabel; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.io.File; +import java.nio.file.Paths; + +public class ECPathUtils { + + public static String getECWOrkDirPathSuffix(String user, String ticketId, String engineType) { + String engineTypeRes = ""; + if (StringUtils.isNotBlank(engineType)) { + engineTypeRes = engineType; + } + File file = + Paths.get( + user, DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd"), engineTypeRes) + .toFile(); + return file.getPath() + File.separator + ticketId; + } + + public static String getECLogDirSuffix( + EngineTypeLabel engineTypeLabel, UserCreatorLabel userCreatorLabel, String ticketId) { + if (null == engineTypeLabel || null == userCreatorLabel) { + return ""; + } + String ecwOrkDirPathSuffix = + ECPathUtils.getECWOrkDirPathSuffix( + userCreatorLabel.getUser(), ticketId, engineTypeLabel.getEngineType()); + return ecwOrkDirPathSuffix + File.separator + "logs"; + } +} diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/exception/GovernanceErrorException.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/exception/GovernanceErrorException.scala index 4168308bd6..544dfcdab6 100644 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/exception/GovernanceErrorException.scala +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/exception/GovernanceErrorException.scala @@ -17,14 +17,15 @@ package org.apache.linkis.governance.common.exception -import org.apache.linkis.common.exception.ErrorException +import org.apache.linkis.common.exception.{ErrorException, ExceptionLevel, LinkisRuntimeException} class GovernanceErrorException(errorCode: Int, errorMsg: String) - extends ErrorException(errorCode, errorMsg) { + extends LinkisRuntimeException(errorCode, errorMsg) { def this(errorCode: Int, errorMsg: String, cause: Throwable) = { this(errorCode, errorMsg) initCause(cause) } + override def getLevel: ExceptionLevel = ExceptionLevel.ERROR } diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/ECPathUtils.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/ECPathUtils.scala deleted file mode 100644 index 747ef4e920..0000000000 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/ECPathUtils.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.linkis.governance.common.utils - -import org.apache.linkis.manager.label.entity.engine.{EngineTypeLabel, UserCreatorLabel} - -import org.apache.commons.lang3.StringUtils -import org.apache.commons.lang3.time.DateFormatUtils - -import java.io.File -import java.nio.file.Paths - -object ECPathUtils { - - def getECWOrkDirPathSuffix(user: String, ticketId: String, engineType: String): String = { - Paths - .get( - user, - DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd"), - if (StringUtils.isBlank(engineType)) "" else engineType - ) - .toFile - .getPath + File.separator + ticketId - - } - - def getECLogDirSuffix( - engineTypeLabel: EngineTypeLabel, - userCreatorLabel: UserCreatorLabel, - ticketId: String - ): String = { - if (null == engineTypeLabel || null == userCreatorLabel) { - return "" - } - val suffix = ECPathUtils.getECWOrkDirPathSuffix( - userCreatorLabel.getUser, - ticketId, - engineTypeLabel.getEngineType - ) - suffix + File.separator + "logs" - } - -} diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.java b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.java new file mode 100644 index 0000000000..c6f8368a1c --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.java @@ -0,0 +1,219 @@ +/* + * 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.linkis.ecm.server.operator; + +import org.apache.linkis.common.conf.CommonVars; +import org.apache.linkis.common.utils.Utils; +import org.apache.linkis.ecm.server.conf.ECMConfiguration; +import org.apache.linkis.ecm.server.exception.ECMErrorException; +import org.apache.linkis.manager.common.operator.Operator; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReversedLinesFileReader; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.Triple; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary.*; + +public class EngineConnLogOperator implements Operator { + private static final Logger logger = LoggerFactory.getLogger(EngineConnLogOperator.class); + + public static final String OPERATOR_NAME = "engineConnLog"; + public static final CommonVars LOG_FILE_NAME = + CommonVars.apply("linkis.engineconn.log.filename", "stdout"); + public static final CommonVars MAX_LOG_FETCH_SIZE = + CommonVars.apply("linkis.engineconn.log.fetch.lines.max", 5000); + public static final CommonVars MAX_LOG_TAIL_START_SIZE = + CommonVars.apply("linkis.engineconn.log.tail.start.size"); + public static final CommonVars MULTILINE_PATTERN = + CommonVars.apply( + "linkis.engineconn.log.multiline.pattern", + "^\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\.\\d{3}"); + public static final CommonVars MULTILINE_MAX = + CommonVars.apply("linkis.engineconn.log.multiline.max", 500); + + @Override + public String[] getNames() { + return new String[] {OPERATOR_NAME}; + } + + @Override + public Map apply(Map parameters) { + File logPath = getLogPath(parameters); + int lastRows = getAs(parameters, "lastRows", 0); + int pageSize = getAs(parameters, "pageSize", 100); + int fromLine = getAs(parameters, "fromLine", 1); + boolean enableTail = getAs(parameters, "enableTail", false); + if (lastRows > EngineConnLogOperator.MAX_LOG_FETCH_SIZE.getValue()) { + throw new ECMErrorException( + CANNOT_FETCH_MORE_THAN.getErrorCode(), + MessageFormat.format( + CANNOT_FETCH_MORE_THAN.getErrorDesc(), + EngineConnLogOperator.MAX_LOG_FETCH_SIZE.getValue().toString())); + } else if (lastRows > 0) { + String logs = Utils.exec(new String[] {"tail", "-n", lastRows + "", logPath.getPath()}, 5000); + Map stringObjectHashMap = new HashMap<>(); + stringObjectHashMap.put("logs", logs.split("\n")); + stringObjectHashMap.put("rows", logs.length()); + return stringObjectHashMap; + } + + String ignoreKeywords = getAs(parameters, "ignoreKeywords", ""); + String[] ignoreKeywordList = + StringUtils.isNotEmpty(ignoreKeywords) ? ignoreKeywords.split(",") : new String[0]; + + String onlyKeywords = getAs(parameters, "onlyKeywords", ""); + String[] onlyKeywordList = + StringUtils.isNotEmpty(onlyKeywords) ? onlyKeywords.split(",") : new String[0]; + + RandomAccessFile randomReader = null; + ReversedLinesFileReader reversedReader = null; + try { + if (enableTail) { + logger.info("enable log operator from tail to read"); + reversedReader = new ReversedLinesFileReader(logPath, Charset.defaultCharset()); + } else { + randomReader = new RandomAccessFile(logPath, "r"); + } + + ArrayList logs = new ArrayList<>(pageSize); + int readLine = 0, skippedLine = 0, lineNum = 0; + boolean rowIgnore = false; + int ignoreLine = 0; + Pattern linePattern = Pattern.compile(EngineConnLogOperator.MULTILINE_PATTERN.getValue()); + + int maxMultiline = MULTILINE_MAX.getValue(); + String line = randomAndReversedReadLine(randomReader, reversedReader); + + while (readLine < pageSize && line != null) { + lineNum += 1; + if (skippedLine < fromLine - 1) { + skippedLine += 1; + } else { + if (rowIgnore) { + Matcher matcher = linePattern.matcher(line); + if (matcher.matches()) { + ignoreLine = 0; + rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList); + } else { + ignoreLine += 1; + if (ignoreLine >= maxMultiline) { + rowIgnore = false; + } + } + if (!matcher.matches()) { + rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList); + } + } else { + rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList); + } + if (!rowIgnore) { + logs.add(line); + readLine += 1; + } + } + line = randomAndReversedReadLine(randomReader, reversedReader); + } + + if (enableTail) { + Collections.reverse(logs); + } + + Map resultMap = new HashMap<>(); + resultMap.put("logPath", logPath.getPath()); + resultMap.put("logs", logs); + resultMap.put("endLine", lineNum); + resultMap.put("rows", readLine); + return resultMap; + } catch (IOException e) { + logger.info("EngineConnLogOperator apply failed", e); + throw new ECMErrorException( + LOG_IS_NOT_EXISTS.getErrorCode(), LOG_IS_NOT_EXISTS.getErrorDesc()); + } finally { + IOUtils.closeQuietly(randomReader); + IOUtils.closeQuietly(reversedReader); + } + } + + private String randomAndReversedReadLine( + RandomAccessFile randomReader, ReversedLinesFileReader reversedReader) throws IOException { + if (randomReader != null) { + String line = randomReader.readLine(); + if (line != null) { + return new String(line.getBytes(StandardCharsets.ISO_8859_1), Charset.defaultCharset()); + } else { + return null; + } + } else { + return reversedReader.readLine(); + } + } + + protected File getLogPath(Map parameters) { + String logType = getAs(parameters, "logType", EngineConnLogOperator.LOG_FILE_NAME.getValue()); + + Triple engineConnInfo = getEngineConnInfo(parameters); + String engineConnLogDir = engineConnInfo.getLeft(); + String engineConnInstance = engineConnInfo.getMiddle(); + String ticketId = engineConnInfo.getRight(); + + File logPath = new File(engineConnLogDir, logType); + if (!logPath.exists() || !logPath.isFile()) { + throw new ECMErrorException( + LOGFILE_IS_NOT_EXISTS.getErrorCode(), + MessageFormat.format(LOGFILE_IS_NOT_EXISTS.getErrorDesc(), logPath.toString())); + } + logger.info( + String.format( + "Try to fetch EngineConn(id: %s, instance: %s) logs from %s.", + ticketId, engineConnInstance, logPath.getPath())); + return logPath; + } + + protected Triple getEngineConnInfo(Map parameters) { + String logDIrSuffix = getAs(parameters, "logDirSuffix", ""); + String engineConnLogDir = + ECMConfiguration.ENGINECONN_ROOT_DIR() + File.separator + logDIrSuffix; + String ticketId = getAs(parameters, "ticketId", ""); + String engineConnInstance = ""; + return Triple.of(engineConnLogDir, engineConnInstance, ticketId); + } + + private boolean includeLine(String line, String[] onlyKeywordList, String[] ignoreKeywordList) { + boolean accept = + ignoreKeywordList.length == 0 || !Arrays.stream(ignoreKeywordList).anyMatch(line::contains); + if (accept) { + accept = + onlyKeywordList.length == 0 || Arrays.stream(onlyKeywordList).anyMatch(line::contains); + } + return accept; + } +} diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.java b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.java new file mode 100644 index 0000000000..e3302df089 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.java @@ -0,0 +1,147 @@ +/* + * 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.linkis.ecm.server.operator; + +import org.apache.linkis.common.exception.WarnException; +import org.apache.linkis.common.utils.Utils; +import org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary; +import org.apache.linkis.ecm.server.exception.ECMErrorException; +import org.apache.linkis.ecm.server.exception.ECMWarnException; + +import org.apache.commons.lang3.tuple.Triple; + +import java.io.File; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary.LOG_IS_NOT_EXISTS; + +public class EngineConnYarnLogOperator extends EngineConnLogOperator { + private static final Logger logger = LoggerFactory.getLogger(EngineConnYarnLogOperator.class); + + @Override + public String[] getNames() { + return new String[] {EngineConnYarnLogOperator.OPERATOR_NAME}; + } + + @Override + public Map apply(Map parameters) { + Map result = new HashMap<>(); + try { + result = super.apply(parameters); + } finally { + Object logPath = result.get("logPath"); + if (logPath instanceof String) { + File logFile = new File((String) logPath); + if (logFile.exists() && logFile.getName().startsWith(".")) { + // If is a temporary file, drop it + logger.info(String.format("Delete the temporary yarn log file: [%s]", logPath)); + if (!logFile.delete()) { + logger.warn(String.format("Fail to delete the temporary yarn log file: [%s]", logPath)); + } + } + } + } + return result; + } + + @Override + public File getLogPath(Map parameters) { + String ticketId, engineConnInstance, engineConnLogDir; + Triple engineConnInfo = getEngineConnInfo(parameters); + ticketId = engineConnInfo.getRight(); + engineConnInstance = engineConnInfo.getMiddle(); + engineConnLogDir = engineConnInfo.getLeft(); + + File rootLogDir = new File(engineConnLogDir); + if (!rootLogDir.exists() || !rootLogDir.isDirectory()) { + throw new ECMWarnException( + LOG_IS_NOT_EXISTS.getErrorCode(), + MessageFormat.format(LOG_IS_NOT_EXISTS.getErrorDesc(), rootLogDir)); + } + + String creator = getAsThrow(parameters, "creator"); + String applicationId = getAsThrow(parameters, "yarnApplicationId"); + File logPath = new File(engineConnLogDir, "yarn_" + applicationId); + if (!logPath.exists()) { + String tempLogFile = + String.format( + ".yarn_%s_%d_%d", + applicationId, System.currentTimeMillis(), Thread.currentThread().getId()); + try { + String command = + String.format( + "yarn logs -applicationId %s >> %s/%s", applicationId, rootLogDir, tempLogFile); + logger.info(String.format("Fetch yarn logs to temporary file: [%s]", command)); + + ProcessBuilder processBuilder = new ProcessBuilder(sudoCommands(creator, command)); + processBuilder.environment().putAll(System.getenv()); + processBuilder.redirectErrorStream(false); + Process process = processBuilder.start(); + boolean waitFor = process.waitFor(5, TimeUnit.SECONDS); + logger.trace(String.format("waitFor: %b, result: %d", waitFor, process.exitValue())); + if (waitFor && process.waitFor() == 0) { + command = + String.format( + "mv %s/%s %s/yarn_%s", rootLogDir, tempLogFile, rootLogDir, applicationId); + logger.info(String.format("Move and save yarn logs: [%s]", command)); + Utils.exec(sudoCommands(creator, command)); + } else { + logPath = new File(engineConnLogDir, tempLogFile); + if (!logPath.exists()) { + throw new WarnException( + -1, + String.format( + "Fetch yarn logs timeout, log aggregation has not completed or is not enabled")); + } + } + } catch (Exception e) { + throw new WarnException( + -1, + String.format( + "Fail to fetch yarn logs application: %s, message: %s", + applicationId, e.getMessage())); + } + } + if (!logPath.exists() || !logPath.isFile()) { + throw new ECMErrorException( + EngineconnServerErrorCodeSummary.LOGFILE_IS_NOT_EXISTS.getErrorCode(), + MessageFormat.format( + EngineconnServerErrorCodeSummary.LOGFILE_IS_NOT_EXISTS.getErrorDesc(), logPath)); + } + logger.info( + String.format( + "Try to fetch EngineConn(id: %s, instance: %s) yarn logs from %s in application id: %s", + ticketId, engineConnInstance, logPath.getPath(), applicationId)); + + return logPath; + } + + private String[] sudoCommands(String creator, String command) { + return new String[] { + "/bin/bash", + "-c", + "sudo su " + creator + " -c \"source ~/.bashrc 2>/dev/null; " + command + "\"" + }; + } +} diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/exception/ECMErrorException.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/exception/ECMErrorException.scala index e50b2ff84f..1b397d04e5 100644 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/exception/ECMErrorException.scala +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/exception/ECMErrorException.scala @@ -17,15 +17,22 @@ package org.apache.linkis.ecm.server.exception -import org.apache.linkis.common.exception.{ErrorException, WarnException} +import org.apache.linkis.common.exception.{ + ErrorException, + ExceptionLevel, + LinkisRuntimeException, + WarnException +} -class ECMErrorException(errorCode: Int, desc: String) extends ErrorException(errorCode, desc) { +class ECMErrorException(errorCode: Int, desc: String) + extends LinkisRuntimeException(errorCode, desc) { def this(errorCode: Int, desc: String, t: Throwable) { this(errorCode, desc) this.initCause(t) } + override def getLevel: ExceptionLevel = ExceptionLevel.ERROR } class ECMWarnException(errCode: Int, desc: String) extends WarnException(errCode, desc) diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.scala deleted file mode 100644 index 40de16849f..0000000000 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnLogOperator.scala +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.linkis.ecm.server.operator - -import org.apache.linkis.common.conf.CommonVars -import org.apache.linkis.common.utils.{Logging, Utils} -import org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary._ -import org.apache.linkis.ecm.server.conf.ECMConfiguration -import org.apache.linkis.ecm.server.exception.ECMErrorException -import org.apache.linkis.ecm.server.service.LocalDirsHandleService -import org.apache.linkis.manager.common.operator.Operator - -import org.apache.commons.io.IOUtils -import org.apache.commons.io.input.ReversedLinesFileReader -import org.apache.commons.lang3.StringUtils - -import java.io.{File, RandomAccessFile} -import java.nio.charset.{Charset, StandardCharsets} -import java.text.MessageFormat -import java.util -import java.util.Collections - -import scala.util.matching.Regex - -class EngineConnLogOperator extends Operator with Logging { - - private var localDirsHandleService: LocalDirsHandleService = _ - - override def getNames: Array[String] = Array(EngineConnLogOperator.OPERATOR_NAME) - - override def apply(implicit parameters: Map[String, Any]): Map[String, Any] = { - val logPath = getLogPath - val lastRows = getAs("lastRows", 0) - val pageSize = getAs("pageSize", 100) - val fromLine = getAs("fromLine", 1) - val enableTail = getAs("enableTail", false) - if (lastRows > EngineConnLogOperator.MAX_LOG_FETCH_SIZE.getValue) { - throw new ECMErrorException( - CANNOT_FETCH_MORE_THAN.getErrorCode, - MessageFormat.format( - CANNOT_FETCH_MORE_THAN.getErrorDesc, - EngineConnLogOperator.MAX_LOG_FETCH_SIZE.getValue.toString - ) - ) - } else if (lastRows > 0) { - val logs = Utils.exec(Array("tail", "-n", lastRows + "", logPath.getPath), 5000).split("\n") - return Map("logs" -> logs, "rows" -> logs.length) - } - - val ignoreKeywords = getAs("ignoreKeywords", "") - val ignoreKeywordList = - if (StringUtils.isNotEmpty(ignoreKeywords)) ignoreKeywords.split(",") - else Array.empty[String] - val onlyKeywords = getAs("onlyKeywords", "") - val onlyKeywordList = - if (StringUtils.isNotEmpty(onlyKeywords)) onlyKeywords.split(",") else Array.empty[String] - var randomReader: RandomAccessFile = null - var reversedReader: ReversedLinesFileReader = null - if (enableTail) { - logger.info("enable log operator from tail to read") - reversedReader = new ReversedLinesFileReader(logPath, Charset.defaultCharset()) - } else { - randomReader = new RandomAccessFile(logPath, "r") - } - def randomAndReversedReadLine(): String = { - if (null != randomReader) { - val line = randomReader.readLine() - if (line != null) { - new String(line.getBytes(StandardCharsets.ISO_8859_1), Charset.defaultCharset()) - } else null - } else { - reversedReader.readLine() - } - } - val logs = new util.ArrayList[String](pageSize) - var readLine, skippedLine, lineNum = 0 - var rowIgnore = false - var ignoreLine = 0 - val linePattern = Option(EngineConnLogOperator.MULTILINE_PATTERN.getValue) match { - case Some(pattern) => pattern.r - case _ => null - } - val maxMultiline = EngineConnLogOperator.MULTILINE_MAX.getValue - Utils.tryFinally { - var line = randomAndReversedReadLine() - while (readLine < pageSize && line != null) { - lineNum += 1 - if (skippedLine < fromLine - 1) { - skippedLine += 1 - } else { - if (rowIgnore) { - linePattern match { - case reg: Regex => - if (reg.findFirstIn(line).isDefined) { - ignoreLine = 0 - rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList) - } else { - ignoreLine += 1 - if (ignoreLine >= maxMultiline) { - rowIgnore = false - } - } - case _ => rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList) - } - } else { - rowIgnore = !includeLine(line, onlyKeywordList, ignoreKeywordList) - } - if (!rowIgnore) { - logs.add(line) - readLine += 1 - } - } - line = randomAndReversedReadLine() - } - } { - IOUtils.closeQuietly(randomReader) - IOUtils.closeQuietly(reversedReader) - } - if (enableTail) Collections.reverse(logs) - Map("logPath" -> logPath.getPath, "logs" -> logs, "endLine" -> lineNum, "rows" -> readLine) - } - - protected def getLogPath(implicit parameters: Map[String, Any]): File = { - val (ticketId, engineConnInstance, engineConnLogDir) = getEngineConnInfo(parameters) - val logPath = - new File(engineConnLogDir, getAs("logType", EngineConnLogOperator.LOG_FILE_NAME.getValue)); - if (!logPath.exists() || !logPath.isFile) { - throw new ECMErrorException( - LOGFILE_IS_NOT_EXISTS.getErrorCode, - MessageFormat.format(LOGFILE_IS_NOT_EXISTS.getErrorDesc, logPath) - ) - } - logger.info( - s"Try to fetch EngineConn(id: $ticketId, instance: $engineConnInstance) logs from ${logPath.getPath}." - ) - logPath - } - - protected def getEngineConnInfo(implicit - parameters: Map[String, Any] - ): (String, String, String) = { - val logDIrSuffix = getAs("logDirSuffix", "") - val ecLogPath = ECMConfiguration.ENGINECONN_ROOT_DIR + File.separator + logDIrSuffix - val ticketId = getAs("ticketId", "") - (ticketId, "", ecLogPath) - } - - private def includeLine( - line: String, - onlyKeywordList: Array[String], - ignoreKeywordList: Array[String] - ): Boolean = { - var accept: Boolean = ignoreKeywordList.isEmpty || !ignoreKeywordList.exists(line.contains) - if (accept) { - accept = onlyKeywordList.isEmpty || onlyKeywordList.exists(line.contains) - } - accept - } - -} - -object EngineConnLogOperator { - val OPERATOR_NAME = "engineConnLog" - val LOG_FILE_NAME = CommonVars("linkis.engineconn.log.filename", "stdout") - val MAX_LOG_FETCH_SIZE = CommonVars("linkis.engineconn.log.fetch.lines.max", 5000) - - val MAX_LOG_TAIL_START_SIZE = CommonVars("linkis.engineconn.log.tail.start.size", 20000) - - // yyyy-MM-dd HH:mm:ss.SSS - val MULTILINE_PATTERN = CommonVars( - "linkis.engineconn.log.multiline.pattern", - "^\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\.\\d{3}" - ) - - val MULTILINE_MAX = CommonVars("linkis.engineconn.log.multiline.max", 500) -} diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.scala deleted file mode 100644 index e00d16b519..0000000000 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/operator/EngineConnYarnLogOperator.scala +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.linkis.ecm.server.operator - -import org.apache.linkis.common.exception.LinkisCommonErrorException -import org.apache.linkis.common.utils.Utils -import org.apache.linkis.ecm.core.conf.ECMErrorCode -import org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary._ -import org.apache.linkis.ecm.server.exception.ECMErrorException - -import java.io.File -import java.text.MessageFormat -import java.util.concurrent.TimeUnit - -import scala.collection.JavaConverters._ - -class EngineConnYarnLogOperator extends EngineConnLogOperator { - - override def getNames: Array[String] = Array(EngineConnYarnLogOperator.OPERATOR_NAME) - - override def apply(implicit parameters: Map[String, Any]): Map[String, Any] = { - var result: Map[String, Any] = Map() - Utils.tryFinally { - result = super.apply(parameters) - result - } { - result.get("logPath") match { - case Some(path: String) => - val logFile = new File(path) - if (logFile.exists() && logFile.getName.startsWith(".")) { - // If is a temporary file, drop it - logger.info(s"Delete the temporary yarn log file: [$path]") - if (!logFile.delete()) { - logger.warn(s"Fail to delete the temporary yarn log file: [$path]") - } - } - } - } - } - - override def getLogPath(implicit parameters: Map[String, Any]): File = { - val (ticketId, engineConnInstance, engineConnLogDir) = getEngineConnInfo(parameters) - val rootLogDir = new File(engineConnLogDir) - if (!rootLogDir.exists() || !rootLogDir.isDirectory) { - throw new ECMErrorException( - LOG_IS_NOT_EXISTS.getErrorCode, - MessageFormat.format(LOG_IS_NOT_EXISTS.getErrorDesc, rootLogDir) - ) - } - val creator = getAsThrow[String]("creator") - val applicationId = getAsThrow[String]("yarnApplicationId") - var logPath = new File(engineConnLogDir, "yarn_" + applicationId) - if (!logPath.exists()) { - val tempLogFile = - s".yarn_${applicationId}_${System.currentTimeMillis()}_${Thread.currentThread().getId}" - Utils.tryCatch { - var command = s"yarn logs -applicationId $applicationId >> $rootLogDir/$tempLogFile" - logger.info(s"Fetch yarn logs to temporary file: [$command]") - val processBuilder = new ProcessBuilder(sudoCommands(creator, command): _*) - processBuilder.environment.putAll(sys.env.asJava) - processBuilder.redirectErrorStream(false) - val process = processBuilder.start() - val waitFor = process.waitFor(5, TimeUnit.SECONDS) - logger.trace(s"waitFor: ${waitFor}, result: ${process.exitValue()}") - if (waitFor && process.waitFor() == 0) { - command = s"mv $rootLogDir/$tempLogFile $rootLogDir/yarn_$applicationId" - logger.info(s"Move and save yarn logs: [$command]") - Utils.exec(sudoCommands(creator, command)) - } else { - logPath = new File(engineConnLogDir, tempLogFile) - if (!logPath.exists()) { - throw new LinkisCommonErrorException( - -1, - s"Fetch yarn logs timeout, log aggregation has not completed or is not enabled" - ) - } - } - } { case e: Exception => - throw new LinkisCommonErrorException( - -1, - s"Fail to fetch yarn logs application: $applicationId, message: ${e.getMessage}" - ) - } - } - if (!logPath.exists() || !logPath.isFile) { - throw new ECMErrorException( - LOGFILE_IS_NOT_EXISTS.getErrorCode, - MessageFormat.format(LOGFILE_IS_NOT_EXISTS.getErrorDesc, logPath) - ) - } - logger.info( - s"Try to fetch EngineConn(id: $ticketId, instance: $engineConnInstance) yarn logs from ${logPath.getPath} in application id: $applicationId" - ) - logPath - } - - private def sudoCommands(creator: String, command: String): Array[String] = { - Array( - "/bin/bash", - "-c", - "sudo su " + creator + " -c \"source ~/.bashrc 2>/dev/null; " + command + "\"" - ) - } - -} - -object EngineConnYarnLogOperator { - val OPERATOR_NAME = "engineConnYarnLog" -} diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/AbstractEngineConnLaunchService.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/AbstractEngineConnLaunchService.scala index c324679175..8ad3031b89 100644 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/AbstractEngineConnLaunchService.scala +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/AbstractEngineConnLaunchService.scala @@ -149,10 +149,11 @@ abstract class AbstractEngineConnLaunchService extends EngineConnLaunchService w Sender .getSender(MANAGER_SERVICE_NAME) .send( - EngineConnStatusCallbackToAM( + new EngineConnStatusCallbackToAM( conn.getServiceInstance, NodeStatus.ShuttingDown, - " wait init failed , reason " + ExceptionUtils.getRootCauseMessage(t) + " wait init failed , reason " + ExceptionUtils.getRootCauseMessage(t), + false ) ) LinkisECMApplication.getContext.getECMSyncListenerBus.postToAll( diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultECMRegisterService.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultECMRegisterService.scala index 4fcddf4c35..ca35b27794 100644 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultECMRegisterService.scala +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultECMRegisterService.scala @@ -98,9 +98,11 @@ class DefaultECMRegisterService extends ECMRegisterService with ECMEventListener logger.info("start register ecm") val response = Sender.getSender(MANAGER_SERVICE_NAME).ask(request) response match { - case RegisterEMResponse(isSuccess, msg) => - if (!isSuccess) { - logger.error(s"Failed to register info to linkis manager, reason: $msg") + case registerEMResponse: RegisterEMResponse => + if (!registerEMResponse.getIsSuccess) { + logger.error( + s"Failed to register info to linkis manager, reason: ${registerEMResponse.getMsg}" + ) System.exit(1) } case _ => diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultOperateService.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultOperateService.scala index 3a541df8b9..12b813d67f 100644 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultOperateService.scala +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/DefaultOperateService.scala @@ -27,26 +27,34 @@ import org.apache.commons.lang3.exception.ExceptionUtils import org.springframework.stereotype.Service -import scala.collection.JavaConverters.mapAsScalaMapConverter +import java.util @Service class DefaultOperateService extends OperateService with Logging { @Receiver override def executeOperation(ecmOperateRequest: ECMOperateRequest): ECMOperateResponse = { - val parameters = ecmOperateRequest.parameters.asScala.toMap - val operator = Utils.tryCatch(OperatorFactory().getOperatorRequest(parameters)) { t => - logger.error(s"Get operator failed, parameters is ${ecmOperateRequest.parameters}.", t) - return ECMOperateResponse(Map.empty, true, ExceptionUtils.getRootCauseMessage(t)) + val parameters = ecmOperateRequest.getParameters() + val operator = Utils.tryCatch(OperatorFactory.apply().getOperatorRequest(parameters)) { t => + logger.error(s"Get operator failed, parameters is ${ecmOperateRequest.getParameters}.", t) + return new ECMOperateResponse( + new util.HashMap[String, Object](), + true, + ExceptionUtils.getRootCauseMessage(t) + ) } logger.info( - s"Try to execute operator ${operator.getClass.getSimpleName} with parameters ${ecmOperateRequest.parameters}." + s"Try to execute operator ${operator.getClass.getSimpleName} with parameters ${ecmOperateRequest.getParameters}." ) val result = Utils.tryCatch(operator(parameters)) { t => logger.error(s"Execute ${operator.getClass.getSimpleName} failed.", t) - return ECMOperateResponse(Map.empty, true, ExceptionUtils.getRootCauseMessage(t)) + return new ECMOperateResponse( + new util.HashMap[String, Object](), + true, + ExceptionUtils.getRootCauseMessage(t) + ) } - ECMOperateResponse(result) + new ECMOperateResponse(result) } } diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/ProcessEngineConnLaunchService.scala b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/ProcessEngineConnLaunchService.scala index e6ab513f15..11bd534563 100644 --- a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/ProcessEngineConnLaunchService.scala +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/scala/org/apache/linkis/ecm/server/service/impl/ProcessEngineConnLaunchService.scala @@ -90,7 +90,7 @@ abstract class ProcessEngineConnLaunchService extends AbstractEngineConnLaunchSe Sender .getSender(MANAGER_SERVICE_NAME) .send( - EngineConnStatusCallbackToAM( + new EngineConnStatusCallbackToAM( conn.getServiceInstance, NodeStatus.ShuttingDown, "Failed to start EngineConn, reason: " + ExceptionUtils.getRootCauseMessage( diff --git a/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/java/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.java b/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/java/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.java new file mode 100644 index 0000000000..3f98e6a988 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/java/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.java @@ -0,0 +1,92 @@ +/* + * 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.linkis.engineconn.once.executor.operator; + +import org.apache.linkis.engineconn.common.exception.EngineConnException; +import org.apache.linkis.engineconn.once.executor.OnceExecutor; +import org.apache.linkis.engineconn.once.executor.OperableOnceExecutor; +import org.apache.linkis.engineconn.once.executor.creation.OnceExecutorManager$; +import org.apache.linkis.manager.common.operator.Operator; +import org.apache.linkis.manager.common.operator.OperatorFactory; +import org.apache.linkis.protocol.engine.JobProgressInfo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OperableOnceEngineConnOperator implements Operator { + + public static final String PROGRESS_OPERATOR_NAME = "engineConnProgress"; + + public static final String METRICS_OPERATOR_NAME = "engineConnMetrics"; + + public static final String DIAGNOSIS_OPERATOR_NAME = "engineConnDiagnosis"; + + @Override + public String[] getNames() { + return new String[] {PROGRESS_OPERATOR_NAME, METRICS_OPERATOR_NAME, DIAGNOSIS_OPERATOR_NAME}; + } + + @Override + public Map apply(Map parameters) { + String operatorName = OperatorFactory.apply().getOperatorName(parameters); + OnceExecutor reportExecutor = OnceExecutorManager$.MODULE$.getInstance().getReportExecutor(); + if (reportExecutor instanceof OperableOnceExecutor) { + OperableOnceExecutor operableOnceExecutor = (OperableOnceExecutor) reportExecutor; + switch (operatorName) { + case PROGRESS_OPERATOR_NAME: + List> progressInfoMap = new ArrayList<>(); + JobProgressInfo[] progressInfoList = operableOnceExecutor.getProgressInfo(); + if (progressInfoList != null && progressInfoList.length != 0) { + for (JobProgressInfo progressInfo : progressInfoList) { + Map infoMap = new HashMap<>(); + infoMap.put("id", progressInfo.id()); + infoMap.put("totalTasks", progressInfo.totalTasks()); + infoMap.put("runningTasks", progressInfo.runningTasks()); + infoMap.put("failedTasks", progressInfo.failedTasks()); + infoMap.put("succeedTasks", progressInfo.succeedTasks()); + progressInfoMap.add(infoMap); + } + } + Map resultMap = new HashMap<>(); + resultMap.put("progress", operableOnceExecutor.getProgress()); + resultMap.put("progressInfo", progressInfoMap); + return resultMap; + case METRICS_OPERATOR_NAME: + return new HashMap() { + { + put("metrics", operableOnceExecutor.getMetrics()); + } + }; + case DIAGNOSIS_OPERATOR_NAME: + return new HashMap() { + { + put("diagnosis", operableOnceExecutor.getDiagnosis()); + } + }; + default: + throw new EngineConnException( + 20308, "This engineConn don't support " + operatorName + " operator."); + } + } else { + throw new EngineConnException( + 20308, "This engineConn don't support " + operatorName + " operator."); + } + } +} diff --git a/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/scala/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.scala b/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/scala/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.scala deleted file mode 100644 index ae1828d1c0..0000000000 --- a/linkis-computation-governance/linkis-engineconn/linkis-clustered-engineconn/linkis-once-engineconn/src/main/scala/org/apache/linkis/engineconn/once/executor/operator/OperableOnceEngineConnOperator.scala +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.linkis.engineconn.once.executor.operator - -import org.apache.linkis.engineconn.common.exception.EngineConnException -import org.apache.linkis.engineconn.once.executor.OperableOnceExecutor -import org.apache.linkis.engineconn.once.executor.creation.OnceExecutorManager -import org.apache.linkis.manager.common.operator.{Operator, OperatorFactory} - -class OperableOnceEngineConnOperator extends Operator { - - import OperableOnceEngineConnOperator._ - - override def getNames: Array[String] = - Array(PROGRESS_OPERATOR_NAME, METRICS_OPERATOR_NAME, DIAGNOSIS_OPERATOR_NAME) - - override def apply(implicit parameters: Map[String, Any]): Map[String, Any] = { - val operatorName = OperatorFactory().getOperatorName(parameters) - OnceExecutorManager.getInstance.getReportExecutor match { - case operableOnceExecutor: OperableOnceExecutor => - operatorName match { - case PROGRESS_OPERATOR_NAME => - val progressInfo = operableOnceExecutor.getProgressInfo - val progressInfoMap = if (progressInfo != null && progressInfo.nonEmpty) { - progressInfo.map(progressInfo => - Map( - "id" -> progressInfo.id, - "totalTasks" -> progressInfo.totalTasks, - "runningTasks" -> progressInfo.runningTasks, - "failedTasks" -> progressInfo.failedTasks, - "succeedTasks" -> progressInfo.succeedTasks - ) - ) - } else Array.empty[Map[String, Any]] - Map("progress" -> operableOnceExecutor.getProgress, "progressInfo" -> progressInfoMap) - case METRICS_OPERATOR_NAME => - Map("metrics" -> operableOnceExecutor.getMetrics) - case DIAGNOSIS_OPERATOR_NAME => - Map("diagnosis" -> operableOnceExecutor.getDiagnosis) - case _ => - throw EngineConnException( - 20308, - s"This engineConn don't support $operatorName operator." - ) - } - case _ => - throw EngineConnException(20308, s"This engineConn don't support $operatorName operator.") - } - } - -} - -object OperableOnceEngineConnOperator { - val PROGRESS_OPERATOR_NAME = "engineConnProgress" - val METRICS_OPERATOR_NAME = "engineConnMetrics" - val DIAGNOSIS_OPERATOR_NAME = "engineConnDiagnosis" -} diff --git a/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/scala/org/apache/linkis/engineconn/computation/executor/service/TaskExecutionServiceImpl.scala b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/scala/org/apache/linkis/engineconn/computation/executor/service/TaskExecutionServiceImpl.scala index f096401c5f..a02ec3dafd 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/scala/org/apache/linkis/engineconn/computation/executor/service/TaskExecutionServiceImpl.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/scala/org/apache/linkis/engineconn/computation/executor/service/TaskExecutionServiceImpl.scala @@ -426,9 +426,10 @@ class TaskExecutionServiceImpl val resourceResponse = buildResourceMap(task) val extraInfoMap = buildExtraInfoMap(task) // todo add other info - val resourceMap = if (null != resourceResponse) resourceResponse.resourceMap else null + val resourceMap = + if (null != resourceResponse) resourceResponse.getResourceMap else null - val respRunningInfo: ResponseTaskRunningInfo = ResponseTaskRunningInfo( + val respRunningInfo: ResponseTaskRunningInfo = new ResponseTaskRunningInfo( progressResponse.execId, progressResponse.progress, progressResponse.progressInfo, @@ -468,7 +469,7 @@ class TaskExecutionServiceImpl taskYarnResource(task.getTaskId) match { case responseTaskYarnResource: ResponseTaskYarnResource => if ( - responseTaskYarnResource.resourceMap != null && !responseTaskYarnResource.resourceMap.isEmpty + responseTaskYarnResource.getResourceMap != null && !responseTaskYarnResource.getResourceMap.isEmpty ) { responseTaskYarnResource } else { @@ -485,7 +486,7 @@ class TaskExecutionServiceImpl executor match { case executor: ResourceFetchExecutor => val resourceWithApplicationId = executor.FetchResource - ResponseTaskYarnResource(taskID, resourceWithApplicationId) + new ResponseTaskYarnResource(taskID, resourceWithApplicationId) case _ => null } } @@ -664,9 +665,9 @@ class TaskExecutionServiceImpl val resourceResponse = buildResourceMap(task) val extraInfoMap = buildExtraInfoMap(task) - val resourceMap = if (null != resourceResponse) resourceResponse.resourceMap else null + val resourceMap = if (null != resourceResponse) resourceResponse.getResourceMap else null - val respRunningInfo: ResponseTaskRunningInfo = ResponseTaskRunningInfo( + val respRunningInfo: ResponseTaskRunningInfo = new ResponseTaskRunningInfo( taskProgressUpdateEvent.taskId, taskProgressUpdateEvent.progress, taskProgressUpdateEvent.progressInfo, diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.java b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.java new file mode 100644 index 0000000000..28a75d3f93 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.java @@ -0,0 +1,56 @@ +/* + * 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.linkis.engineconn.acessible.executor.operator.impl; + +import org.apache.linkis.engineconn.common.exception.EngineConnException; +import org.apache.linkis.engineconn.core.executor.ExecutorManager$; +import org.apache.linkis.engineconn.core.executor.LabelExecutorManager; +import org.apache.linkis.engineconn.executor.entity.Executor; +import org.apache.linkis.engineconn.executor.entity.YarnExecutor; +import org.apache.linkis.manager.common.operator.Operator; + +import java.util.HashMap; +import java.util.Map; + +public class EngineConnApplicationInfoOperator implements Operator { + + public static final String OPERATOR_NAME = "engineConnYarnApplication"; + + @Override + public String[] getNames() { + return new String[] {OPERATOR_NAME}; + } + + @Override + public Map apply(Map parameters) { + LabelExecutorManager instance = ExecutorManager$.MODULE$.getInstance(); + Executor reportExecutor = instance.getReportExecutor(); + if (reportExecutor instanceof YarnExecutor) { + YarnExecutor yarnExecutor = (YarnExecutor) reportExecutor; + Map result = new HashMap<>(); + result.put("applicationId", yarnExecutor.getApplicationId()); + result.put("applicationUrl", yarnExecutor.getApplicationURL()); + result.put("queue", yarnExecutor.getQueue()); + result.put("yarnMode", yarnExecutor.getYarnMode()); + return result; + } else { + throw new EngineConnException( + 20301, "EngineConn is not a yarn application, cannot fetch applicaiton info."); + } + } +} diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/execution/AccessibleEngineConnExecution.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/execution/AccessibleEngineConnExecution.scala index 1b5713e568..0bd7ececef 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/execution/AccessibleEngineConnExecution.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/execution/AccessibleEngineConnExecution.scala @@ -204,7 +204,7 @@ class AccessibleEngineConnExecution extends EngineConnExecution with Logging { case resourceExecutor: ResourceExecutor => ManagerService.getManagerService .reportUsedResource( - ResourceUsedProtocol( + new ResourceUsedProtocol( Sender.getThisServiceInstance, resourceExecutor.getCurrentNodeResource(), engineCreationContext.getTicketId diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.scala deleted file mode 100644 index ad762892ef..0000000000 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/operator/impl/EngineConnApplicationInfoOperator.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.linkis.engineconn.acessible.executor.operator.impl - -import org.apache.linkis.engineconn.common.exception.EngineConnException -import org.apache.linkis.engineconn.core.executor.ExecutorManager -import org.apache.linkis.engineconn.executor.entity.YarnExecutor -import org.apache.linkis.manager.common.operator.Operator - -class EngineConnApplicationInfoOperator extends Operator { - - override def getNames: Array[String] = Array(EngineConnApplicationInfoOperator.OPERATOR_NAME) - - override def apply(implicit parameters: Map[String, Any]): Map[String, Any] = { - ExecutorManager.getInstance.getReportExecutor match { - case yarnExecutor: YarnExecutor => - Map( - "applicationId" -> yarnExecutor.getApplicationId, - "applicationUrl" -> yarnExecutor.getApplicationURL, - "queue" -> yarnExecutor.getQueue, - "yarnMode" -> yarnExecutor.getYarnMode - ) - case _ => - throw EngineConnException( - 20301, - "EngineConn is not a yarn application, cannot fetch applicaiton info." - ) - } - } - -} - -object EngineConnApplicationInfoOperator { - val OPERATOR_NAME = "engineConnYarnApplication" -} diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultManagerService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultManagerService.scala index 1ab5a16265..bc410c7186 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultManagerService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultManagerService.scala @@ -57,7 +57,8 @@ class DefaultManagerService extends ManagerService with Logging { logger.info("engineType labels is empty, Not reported") return } - val labelReportRequest = LabelReportRequest(reportLabel.asJava, Sender.getThisServiceInstance) + val labelReportRequest = + new LabelReportRequest(reportLabel.asJava, Sender.getThisServiceInstance) getManagerSender.send(labelReportRequest) } diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultOperateService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultOperateService.scala index df34626c20..1040df40a6 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultOperateService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultOperateService.scala @@ -29,7 +29,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils import org.springframework.stereotype.Service -import scala.collection.JavaConverters.mapAsScalaMapConverter +import java.util @Service class DefaultOperateService extends OperateService with Logging { @@ -38,19 +38,27 @@ class DefaultOperateService extends OperateService with Logging { override def executeOperation( engineOperateRequest: EngineOperateRequest ): EngineOperateResponse = { - val parameters = engineOperateRequest.parameters.asScala.toMap - val operator = Utils.tryCatch(OperatorFactory().getOperatorRequest(parameters)) { t => - logger.error(s"Get operator failed, parameters is ${engineOperateRequest.parameters}.", t) - return EngineOperateResponse(Map.empty, true, ExceptionUtils.getRootCauseMessage(t)) + val parameters = engineOperateRequest.getParameters() + val operator = Utils.tryCatch(OperatorFactory.apply().getOperatorRequest(parameters)) { t => + logger.error(s"Get operator failed, parameters is ${engineOperateRequest.getParameters}.", t) + return new EngineOperateResponse( + new util.HashMap, + true, + ExceptionUtils.getRootCauseMessage(t) + ) } logger.info( - s"Try to execute operator ${operator.getClass.getSimpleName} with parameters ${engineOperateRequest.parameters}." + s"Try to execute operator ${operator.getClass.getSimpleName} with parameters ${engineOperateRequest.getParameters}." ) val result = Utils.tryCatch(operator(parameters)) { t => logger.error(s"Execute ${operator.getClass.getSimpleName} failed.", t) - return EngineOperateResponse(Map.empty, true, ExceptionUtils.getRootCauseMessage(t)) + return new EngineOperateResponse( + new util.HashMap, + true, + ExceptionUtils.getRootCauseMessage(t) + ) } - EngineOperateResponse(result) + new EngineOperateResponse(result) } } diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/EngineConnTimedLockService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/EngineConnTimedLockService.scala index 452c6305b0..957a03b6f7 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/EngineConnTimedLockService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/EngineConnTimedLockService.scala @@ -81,12 +81,12 @@ class EngineConnTimedLockService extends LockService with Logging { @throws[EngineConnExecutorErrorException] override def tryLock(requestEngineLock: RequestEngineLock): Option[String] = synchronized { if (null != engineConnLock && engineConnLock.isAcquired()) return None - this.lockType = requestEngineLock.lockType + this.lockType = requestEngineLock.getLockType lockType match { case EngineLockType.Always => timedLock(-1) case EngineLockType.Timed => - timedLock(requestEngineLock.timeout) + timedLock(requestEngineLock.getTimeout) case o: Any => logger.error("Invalid lockType : " + BDPJettyServerHelper.gson.toJson(o)) return Some(null) @@ -174,11 +174,11 @@ class EngineConnTimedLockService extends LockService with Logging { @Receiver override def requestUnLock(requestEngineUnlock: RequestEngineUnlock): ResponseEngineUnlock = { - if (StringUtils.isBlank(requestEngineUnlock.lock)) { + if (StringUtils.isBlank(requestEngineUnlock.getLock)) { logger.error("Invalid requestEngineUnlock: ") - ResponseEngineUnlock(false) + new ResponseEngineUnlock(false) } else { - ResponseEngineUnlock(unlock(requestEngineUnlock.lock)) + new ResponseEngineUnlock(unlock(requestEngineUnlock.getLock)) } } @@ -223,7 +223,7 @@ class EngineConnConcurrentLockService extends LockService { @Receiver override def requestUnLock(requestEngineUnlock: RequestEngineUnlock): ResponseEngineUnlock = - ResponseEngineUnlock(true) + new ResponseEngineUnlock(true) override def onAddLock(addLockEvent: ExecutorLockEvent): Unit = {} diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/LockService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/LockService.scala index 0860076e40..28e4720953 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/LockService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/LockService.scala @@ -49,14 +49,15 @@ trait LockService extends ExecutorLockListener with Logging { // Engine can be locked if (!StringUtils.isBlank(lockStr)) { // lock success - response = ResponseEngineLock(true, lockStr, s"Lock for ${requestEngineLock.timeout} ms") + response = + new ResponseEngineLock(true, lockStr, s"Lock for ${requestEngineLock.getTimeout} ms") } else { // lock failed - response = ResponseEngineLock(false, lockStr, "lock str is blank") + response = new ResponseEngineLock(false, lockStr, "lock str is blank") } case None => // Engine is busy - response = ResponseEngineLock(false, null, "Engine is busy.") + response = new ResponseEngineLock(false, null, "Engine is busy.") } logger.info( "RequestLock : " + BDPJettyServerHelper.gson.toJson( diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/hook/CallbackEngineConnHook.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/hook/CallbackEngineConnHook.scala index fa7d9ff010..4261e8efd4 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/hook/CallbackEngineConnHook.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/hook/CallbackEngineConnHook.scala @@ -82,7 +82,7 @@ class CallbackEngineConnHook extends EngineConnHook with Logging { val prefixMsg = Sender.getThisServiceInstance + s": log dir: ${EngineConnConf.getLogDir}," Utils.tryAndError( engineConnAfterStartCallback.callback( - EngineConnStatusCallback( + new EngineConnStatusCallback( Sender.getThisServiceInstance, engineCreationContext.getTicketId, NodeStatus.Failed, @@ -106,7 +106,7 @@ class CallbackEngineConnHook extends EngineConnHook with Logging { val engineConnAfterStartCallback = new EngineConnAfterStartCallback Utils.tryAndError( engineConnAfterStartCallback.callback( - EngineConnStatusCallback( + new EngineConnStatusCallback( Sender.getThisServiceInstance, engineCreationContext.getTicketId, getNodeStatusOfStartSuccess(engineCreationContext, engineConn), diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/service/EngineConnCallback.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/service/EngineConnCallback.scala index 1b629cf30c..39ed9afff4 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/service/EngineConnCallback.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/callback/service/EngineConnCallback.scala @@ -35,7 +35,7 @@ abstract class AbstractEngineConnStartUpCallback() extends EngineConnCallback wi def callback(protocol: RequestProtocol): Unit = { protocol match { case protocol: EngineConnStatusCallback => - if (protocol.status.equals(NodeStatus.Failed)) { + if (protocol.getStatus().equals(NodeStatus.Failed)) { logger.error(s"protocol will send to lm: ${protocol}") } else { logger.info(s"protocol will send to lm: ${protocol}") diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/scala/org/apache/linkis/manager/engineplugin/common/exception/EngineConnPluginErrorException.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/scala/org/apache/linkis/manager/engineplugin/common/exception/EngineConnPluginErrorException.scala index 41cf435459..d7ab70908a 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/scala/org/apache/linkis/manager/engineplugin/common/exception/EngineConnPluginErrorException.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/scala/org/apache/linkis/manager/engineplugin/common/exception/EngineConnPluginErrorException.scala @@ -17,6 +17,9 @@ package org.apache.linkis.manager.engineplugin.common.exception -import org.apache.linkis.common.exception.ErrorException +import org.apache.linkis.common.exception.{ErrorException, ExceptionLevel, LinkisRuntimeException} -class EngineConnPluginErrorException(code: Int, msg: String) extends ErrorException(code, msg) {} +class EngineConnPluginErrorException(code: Int, msg: String) + extends LinkisRuntimeException(code, msg) { + override def getLevel: ExceptionLevel = ExceptionLevel.ERROR +} diff --git a/linkis-computation-governance/linkis-entrance/src/main/java/org/apache/linkis/entrance/restful/EntranceRestfulApi.java b/linkis-computation-governance/linkis-entrance/src/main/java/org/apache/linkis/entrance/restful/EntranceRestfulApi.java index a5d3ace35f..87ac92f6b2 100644 --- a/linkis-computation-governance/linkis-entrance/src/main/java/org/apache/linkis/entrance/restful/EntranceRestfulApi.java +++ b/linkis-computation-governance/linkis-entrance/src/main/java/org/apache/linkis/entrance/restful/EntranceRestfulApi.java @@ -338,7 +338,7 @@ public Message progressWithResource(HttpServletRequest req, @PathVariable("id") metricsVo.put(TaskConstant.JOB_YARNRESOURCE, resoureList); Optional cores = resourceMap.values().stream() - .map(resource -> resource.queueCores()) + .map(resource -> resource.getQueueCores()) .reduce((x, y) -> x + y); Optional memory = resourceMap.values().stream() diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/EngineConnPluginLoaderConf.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/EngineConnPluginLoaderConf.java new file mode 100644 index 0000000000..59d9959431 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/EngineConnPluginLoaderConf.java @@ -0,0 +1,44 @@ +/* + * 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.linkis.engineplugin.loader; + +import org.apache.linkis.common.conf.CommonVars; +import org.apache.linkis.common.conf.Configuration; + +public class EngineConnPluginLoaderConf { + + public static final CommonVars ENGINE_PLUGIN_LOADER_DEFAULT_USER = + CommonVars.apply("wds.linkis.engineconn.plugin.loader.defaultUser", "hadoop"); + + public static final CommonVars ENGINE_PLUGIN_STORE_PATH = + CommonVars.apply( + "wds.linkis.engineconn.plugin.loader.store.path", + CommonVars.apply( + "ENGINE_CONN_HOME", + Configuration.getLinkisHome() + "/lib/linkis-engineconn-plugins") + .getValue()); + + public static final CommonVars ENGINE_PLUGIN_PROPERTIES_NAME = + CommonVars.apply("wds.linkis.engineconn.plugin.loader.properties.name", "plugins.properties"); + + public static final CommonVars ENGINE_PLUGIN_LOADER_CACHE_REFRESH_INTERVAL = + CommonVars.apply("wds.linkis.engineconn.plugin.loader.cache.refresh-interval", "300"); + + public static final CommonVars DOWNLOAD_TEMP_DIR_PREFIX = + CommonVars.apply("wds.linkis.engineconn.plugin.loader.download.tmpdir.prefix", ".BML_TMP_"); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/CacheablesEngineConnPluginLoader.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/CacheablesEngineConnPluginLoader.java index ef72664460..059f984fa4 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/CacheablesEngineConnPluginLoader.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/CacheablesEngineConnPluginLoader.java @@ -59,8 +59,7 @@ public CacheablesEngineConnPluginLoader() { @Override public long interval() { return Long.parseLong( - EngineConnPluginLoaderConf.ENGINE_PLUGIN_LOADER_CACHE_REFRESH_INTERVAL() - .getValue()); + EngineConnPluginLoaderConf.ENGINE_PLUGIN_LOADER_CACHE_REFRESH_INTERVAL.getValue()); } @Override diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/DefaultEngineConnPluginLoader.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/DefaultEngineConnPluginLoader.java index 0e54ed8c4e..e3ae5ccde1 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/DefaultEngineConnPluginLoader.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/DefaultEngineConnPluginLoader.java @@ -17,13 +17,12 @@ package org.apache.linkis.engineplugin.loader.loaders; -import org.apache.linkis.common.exception.ErrorException; import org.apache.linkis.engineplugin.loader.EngineConnPluginLoaderConf; import org.apache.linkis.engineplugin.loader.classloader.EngineConnPluginClassLoader; import org.apache.linkis.engineplugin.loader.loaders.resource.LocalEngineConnPluginResourceLoader; import org.apache.linkis.engineplugin.loader.loaders.resource.PluginResource; import org.apache.linkis.engineplugin.loader.utils.EngineConnPluginUtils; -import org.apache.linkis.engineplugin.loader.utils.ExceptionHelper; +import org.apache.linkis.manager.am.exception.AMErrorException; import org.apache.linkis.manager.engineplugin.common.EngineConnPlugin; import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginLoadException; import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginNotFoundException; @@ -58,17 +57,16 @@ public class DefaultEngineConnPluginLoader extends CacheablesEngineConnPluginLoa private static final String PLUGIN_DIR = "plugin"; - public DefaultEngineConnPluginLoader() throws ErrorException { + public DefaultEngineConnPluginLoader() { // Check store path (is necessary) - String storePath = EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH().getValue(); + String storePath = EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH.getValue(); LOG.info("DefaultEngineConnPluginLoader, storePath:" + storePath); if (StringUtils.isBlank(storePath)) { - ExceptionHelper.dealErrorException( + throw new AMErrorException( 70061, "You should defined [" - + EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH().key() - + "] in properties file", - null); + + EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH.key() + + "] in properties file"); } // The path can be uri try { @@ -80,17 +78,14 @@ public DefaultEngineConnPluginLoader() throws ErrorException { } catch (URISyntaxException e) { // Ignore } catch (IllegalArgumentException e) { - ExceptionHelper.dealErrorException( + throw new AMErrorException( 70061, - "The value:[" - + storePath - + "] of [" - + EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH().key() - + "] is incorrect", - e); + "You should defined [" + + EngineConnPluginLoaderConf.ENGINE_PLUGIN_STORE_PATH.key() + + "] in properties file"); } this.rootStorePath = storePath; - this.pluginPropsName = EngineConnPluginLoaderConf.ENGINE_PLUGIN_PROPERTIES_NAME().getValue(); + this.pluginPropsName = EngineConnPluginLoaderConf.ENGINE_PLUGIN_PROPERTIES_NAME.getValue(); // Prepare inner loaders // resourceLoaders.add(new BmlEngineConnPluginResourceLoader()); resourceLoaders.add(new LocalEngineConnPluginResourceLoader()); diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/resource/BmlEngineConnPluginResourceLoader.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/resource/BmlEngineConnPluginResourceLoader.java index 8b8a071480..23607a7063 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/resource/BmlEngineConnPluginResourceLoader.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/loader/loaders/resource/BmlEngineConnPluginResourceLoader.java @@ -58,13 +58,13 @@ public class BmlEngineConnPluginResourceLoader implements EngineConnPluginsResou private String downloadTmpDir; public BmlEngineConnPluginResourceLoader() { - this(EngineConnPluginLoaderConf.ENGINE_PLUGIN_LOADER_DEFAULT_USER().getValue(), null); + this(EngineConnPluginLoaderConf.ENGINE_PLUGIN_LOADER_DEFAULT_USER.getValue(), null); } public BmlEngineConnPluginResourceLoader(String clientUser, Map clientProps) { this.clientUser = clientUser; this.bmlClient = BmlClientFactory.createBmlClient(clientUser, clientProps); - this.downloadTmpDir = EngineConnPluginLoaderConf.DOWNLOAD_TEMP_DIR_PREFIX().getValue(); + this.downloadTmpDir = EngineConnPluginLoaderConf.DOWNLOAD_TEMP_DIR_PREFIX.getValue(); } @Override diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/conf/EngineConnPluginConfiguration.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/conf/EngineConnPluginConfiguration.java new file mode 100644 index 0000000000..395471e78b --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/conf/EngineConnPluginConfiguration.java @@ -0,0 +1,42 @@ +/* + * 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.linkis.engineplugin.server.conf; + +import org.apache.linkis.common.conf.CommonVars; +import org.apache.linkis.common.conf.Configuration; + +public class EngineConnPluginConfiguration { + + public static final CommonVars ENGINE_CONN_HOME = + CommonVars.apply( + "wds.linkis.engineconn.home", + CommonVars.apply( + "ENGINE_CONN_HOME", + Configuration.getLinkisHome() + "/lib/linkis-engineconn-plugins") + .getValue()); + + public static final CommonVars ENGINE_CONN_DIST_LOAD_ENABLE = + CommonVars.apply("wds.linkis.engineconn.dist.load.enable", true); + + public static final CommonVars ENABLED_BML_UPLOAD_FAILED_EXIT = + CommonVars.apply("wds.linkis.engineconn.bml.upload.failed.enable", true); + + // for third party eg appconn/datax, if all update, can set to false then to remove + public static final CommonVars EC_BML_VERSION_MAY_WITH_PREFIX_V = + CommonVars.apply("linkis.engineconn.bml.version.may.with.prefix", true); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.java similarity index 76% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.java index e88783185f..0b5e7ad129 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/interceptor/EngineConnLaunchInterceptor.java @@ -15,20 +15,16 @@ * limitations under the License. */ -package org.apache.linkis.engineplugin.server.interceptor +package org.apache.linkis.engineplugin.server.interceptor; -import org.apache.linkis.manager.engineplugin.common.launch.entity.{ - EngineConnBuildRequest, - RicherEngineConnBuildRequest -} - -trait EngineConnLaunchInterceptor { +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnBuildRequest; +import org.apache.linkis.manager.engineplugin.common.launch.entity.RicherEngineConnBuildRequest; +interface EngineConnLaunchInterceptor { /** * 补充资源文件信息,如:UDF、用户jar、Python文件等 补充启动参数信息等 * * @param engineConnBuildRequest */ - def intercept(engineConnBuildRequest: EngineConnBuildRequest): RicherEngineConnBuildRequest - + RicherEngineConnBuildRequest intercept(EngineConnBuildRequest engineConnBuildRequest); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/loader/EngineConnPluginsLoaderFactory.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/loader/EngineConnPluginsLoaderFactory.java new file mode 100644 index 0000000000..280c35d660 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/loader/EngineConnPluginsLoaderFactory.java @@ -0,0 +1,31 @@ +/* + * 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.linkis.engineplugin.server.loader; + +import org.apache.linkis.engineplugin.loader.loaders.DefaultEngineConnPluginLoader; + +public class EngineConnPluginsLoaderFactory { + + private static final org.apache.linkis.engineplugin.loader.loaders.EngineConnPluginsLoader + engineConnPluginsLoader = new DefaultEngineConnPluginLoader(); + + public static org.apache.linkis.engineplugin.loader.loaders.EngineConnPluginsLoader + getEngineConnPluginsLoader() { + return engineConnPluginsLoader; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/AbstractEngineConnBmlResourceGenerator.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/AbstractEngineConnBmlResourceGenerator.java new file mode 100644 index 0000000000..ae9f01ff6d --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/AbstractEngineConnBmlResourceGenerator.java @@ -0,0 +1,134 @@ +/* + * 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.linkis.engineplugin.server.localize; + +import org.apache.linkis.engineplugin.server.conf.EngineConnPluginConfiguration; +import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginErrorException; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; + +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary.*; + +public abstract class AbstractEngineConnBmlResourceGenerator + implements EngineConnBmlResourceGenerator { + + private static final Logger logger = + LoggerFactory.getLogger(AbstractEngineConnBmlResourceGenerator.class); + + public AbstractEngineConnBmlResourceGenerator() { + if (!new File(getEngineConnsHome()).exists()) { + throw new EngineConnPluginErrorException( + CANNOT_HOME_PATH_EC.getErrorCode(), + MessageFormat.format(CANNOT_HOME_PATH_EC.getErrorDesc(), getEngineConnsHome())); + } + } + + public String getEngineConnsHome() { + return EngineConnPluginConfiguration.ENGINE_CONN_HOME.getValue(); + } + + protected String getEngineConnDistHome(EngineTypeLabel engineConnTypeLabel) { + return getEngineConnDistHome( + engineConnTypeLabel.getEngineType(), engineConnTypeLabel.getVersion()); + } + + protected String getEngineConnDistHome(String engineConnType, String version) { + String engineConnDistHome = + Paths.get(getEngineConnsHome(), engineConnType, "dist").toFile().getPath(); + checkEngineConnDistHome(engineConnDistHome); + if (StringUtils.isBlank(version) + || EngineConnBmlResourceGenerator.NO_VERSION_MARK.equals(version)) { + return engineConnDistHome; + } + String engineConnPackageHome = Paths.get(engineConnDistHome, version).toFile().getPath(); + logger.info("getEngineConnDistHome, engineConnPackageHome path:" + engineConnPackageHome); + File engineConnPackageHomeFile = new File(engineConnPackageHome); + if (!engineConnPackageHomeFile.exists()) { + if (!version.startsWith("v") + && (boolean) EngineConnPluginConfiguration.EC_BML_VERSION_MAY_WITH_PREFIX_V.getValue()) { + String versionOld = "v" + version; + String engineConnPackageHomeOld = + Paths.get(engineConnDistHome, versionOld).toFile().getPath(); + logger.info( + "try to getEngineConnDistHome with prefix v, engineConnPackageHome path:" + + engineConnPackageHomeOld); + File engineConnPackageHomeFileOld = new File(engineConnPackageHomeOld); + if (!engineConnPackageHomeFileOld.exists()) { + throw new EngineConnPluginErrorException( + ENGINE_VERSION_NOT_FOUND.getErrorCode(), + MessageFormat.format( + ENGINE_VERSION_NOT_FOUND.getErrorDesc(), version, engineConnType)); + } else { + return engineConnPackageHomeOld; + } + } else { + throw new EngineConnPluginErrorException( + ENGINE_VERSION_NOT_FOUND.getErrorCode(), + MessageFormat.format(ENGINE_VERSION_NOT_FOUND.getErrorDesc(), version, engineConnType)); + } + } else { + return engineConnPackageHome; + } + } + + private void checkEngineConnDistHome(String engineConnPackageHomePath) { + File engineConnPackageHomeFile = new File(engineConnPackageHomePath); + checkEngineConnDistHome(engineConnPackageHomeFile); + } + + private void checkEngineConnDistHome(File engineConnPackageHome) { + if (!engineConnPackageHome.exists()) { + throw new EngineConnPluginErrorException( + CANNOT_HOME_PATH_DIST.getErrorCode(), + MessageFormat.format( + CANNOT_HOME_PATH_DIST.getErrorDesc(), engineConnPackageHome.getPath())); + } + } + + protected String[] getEngineConnDistHomeList(String engineConnType) { + String engineConnDistHome = + Paths.get(getEngineConnsHome(), engineConnType, "dist").toFile().getPath(); + File engineConnDistHomeFile = new File(engineConnDistHome); + checkEngineConnDistHome(engineConnDistHomeFile); + File[] children = engineConnDistHomeFile.listFiles(); + if (children.length == 0) { + throw new EngineConnPluginErrorException( + DIST_IS_EMPTY.getErrorCode(), + MessageFormat.format(DIST_IS_EMPTY.getErrorDesc(), engineConnType)); + } else { + return Arrays.stream(children).map(File::getPath).toArray(String[]::new); + } + } + + @Override + public String[] getEngineConnTypeListFromDisk() { + return Arrays.stream(new File(getEngineConnsHome()).listFiles()) + .filter(file -> !file.isHidden()) + .map(file -> file.getName()) + .toArray(String[]::new); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/DefaultEngineConnBmlResourceGenerator.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/DefaultEngineConnBmlResourceGenerator.java new file mode 100644 index 0000000000..b018d2ce7f --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/DefaultEngineConnBmlResourceGenerator.java @@ -0,0 +1,109 @@ +/* + * 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.linkis.engineplugin.server.localize; + +import org.apache.linkis.common.utils.ZipUtils; +import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginErrorException; + +import java.io.File; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary.CONTAINS_SPECIAL_CHARCATERS; +import static org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary.NO_PERMISSION_FILE; + +public class DefaultEngineConnBmlResourceGenerator extends AbstractEngineConnBmlResourceGenerator { + + private static final Logger logger = + LoggerFactory.getLogger(DefaultEngineConnBmlResourceGenerator.class); + + public DefaultEngineConnBmlResourceGenerator() {} + + @Override + public Map generate(String engineConnType) { + String[] engineConnDistHomes = getEngineConnDistHomeList(engineConnType); + Map resultMap = new HashMap<>(); + for (String path : engineConnDistHomes) { + + File versionFile = new File(path); + logger.info("generate, versionFile:" + path); + String key = versionFile.getName(); + if (key.contains("-")) { + throw new EngineConnPluginErrorException( + CONTAINS_SPECIAL_CHARCATERS.getErrorCode(), + MessageFormat.format(CONTAINS_SPECIAL_CHARCATERS.getErrorDesc(), engineConnType)); + } + + try { + EngineConnLocalizeResource[] engineConnLocalizeResources = + generateDir(versionFile.getPath()); + resultMap.put(key, engineConnLocalizeResources); + } catch (Throwable t) { + logger.error("Generate dir : " + path + " error, msg : " + t.getMessage(), t); + throw t; + } + } + + return resultMap; + } + + @Override + public EngineConnLocalizeResource[] generate(String engineConnType, String version) { + String path = getEngineConnDistHome(engineConnType, version); + return generateDir(path); + } + + private EngineConnLocalizeResource[] generateDir(String path) { + File distFile = new File(path); + logger.info("generateDir, distFile:" + path); + File[] validFiles = + distFile.listFiles( + f -> + !f.getName().endsWith(".zip") + || !new File(path, f.getName().replace(".zip", "")).exists()); + + return Arrays.stream(validFiles) + .map( + file -> { + if (file.isFile()) { + return new EngineConnLocalizeResourceImpl( + file.getPath(), file.getName(), file.lastModified(), file.length()); + } else { + File newFile = new File(path, file.getName() + ".zip"); + if (newFile.exists() && !newFile.delete()) { + throw new EngineConnPluginErrorException( + NO_PERMISSION_FILE.getErrorCode(), + MessageFormat.format(NO_PERMISSION_FILE.getErrorDesc(), newFile)); + } + + ZipUtils.fileToZip(file.getPath(), path, file.getName() + ".zip"); + // If it is a folder, the last update time here is the last update time of the + // folder, not the last update time of + // ZIP.(如果是文件夹,这里的最后更新时间,采用文件夹的最后更新时间,而不是ZIP的最后更新时间.) + return new EngineConnLocalizeResourceImpl( + newFile.getPath(), newFile.getName(), file.lastModified(), newFile.length()); + } + }) + .toArray(EngineConnLocalizeResource[]::new); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnBmlResourceGenerator.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnBmlResourceGenerator.java new file mode 100644 index 0000000000..35a46fff60 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnBmlResourceGenerator.java @@ -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. + */ + +package org.apache.linkis.engineplugin.server.localize; + +import java.util.Map; + +public interface EngineConnBmlResourceGenerator { + String NO_VERSION_MARK = "_default_"; + + String[] getEngineConnTypeListFromDisk(); + + Map generate(String engineConnType); + + EngineConnLocalizeResource[] generate(String engineConnType, String version); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResource.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResource.java new file mode 100644 index 0000000000..8e6408c72b --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResource.java @@ -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. + */ + +package org.apache.linkis.engineplugin.server.localize; + +import java.io.InputStream; + +public interface EngineConnLocalizeResource { + String fileName(); + + long lastModified(); + + long fileSize(); + + InputStream getFileInputStream(); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResourceImpl.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResourceImpl.java new file mode 100644 index 0000000000..4ca366e8bf --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/localize/EngineConnLocalizeResourceImpl.java @@ -0,0 +1,69 @@ +/* + * 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.linkis.engineplugin.server.localize; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EngineConnLocalizeResourceImpl implements EngineConnLocalizeResource { + private static final Logger logger = + LoggerFactory.getLogger(EngineConnLocalizeResourceImpl.class); + + private final String filePath; + private final String fileName; + private final long lastModified; + private final long fileSize; + + public EngineConnLocalizeResourceImpl( + String filePath, String fileName, long lastModified, long fileSize) { + this.filePath = filePath; + this.fileName = fileName; + this.lastModified = lastModified; + this.fileSize = fileSize; + } + + @Override + public InputStream getFileInputStream() { + try { + return new FileInputStream(filePath); + } catch (FileNotFoundException e) { + logger.warn("getFileInputStream failed filePath:[{}]", filePath, e); + } + return null; + } + + public String filePath() { + return filePath; + } + + public String fileName() { + return fileName; + } + + public long lastModified() { + return lastModified; + } + + public long fileSize() { + return fileSize; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnLaunchService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnLaunchService.java new file mode 100644 index 0000000000..807daa2c97 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnLaunchService.java @@ -0,0 +1,106 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.engineplugin.server.loader.EngineConnPluginsLoaderFactory; +import org.apache.linkis.manager.am.exception.AMErrorCode; +import org.apache.linkis.manager.am.util.LinkisUtils; +import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginErrorException; +import org.apache.linkis.manager.engineplugin.common.launch.EngineConnLaunchBuilder; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnBuildRequest; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnLaunchRequest; +import org.apache.linkis.manager.engineplugin.common.launch.process.EngineConnResourceGenerator; +import org.apache.linkis.manager.engineplugin.common.launch.process.JavaProcessEngineConnLaunchBuilder; +import org.apache.linkis.manager.engineplugin.common.loader.entity.EngineConnPluginInstance; +import org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.rpc.message.annotation.Receiver; + +import org.apache.commons.lang3.exception.ExceptionUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class DefaultEngineConnLaunchService implements EngineConnLaunchService { + + private static final Logger logger = + LoggerFactory.getLogger(DefaultEngineConnLaunchService.class); + + @Autowired private EngineConnResourceGenerator engineConnResourceGenerator; + + private EngineConnLaunchBuilder getEngineLaunchBuilder( + EngineTypeLabel engineTypeLabel, EngineConnBuildRequest engineBuildRequest) { + final EngineConnPluginInstance engineConnPluginInstance; + try { + engineConnPluginInstance = + EngineConnPluginsLoaderFactory.getEngineConnPluginsLoader() + .getEngineConnPlugin(engineTypeLabel); + } catch (Exception e) { + throw new EngineConnPluginErrorException( + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorCode(), + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorDesc()); + } + final EngineConnLaunchBuilder builder = + engineConnPluginInstance.plugin().getEngineConnLaunchBuilder(); + if (builder instanceof JavaProcessEngineConnLaunchBuilder) { + ((JavaProcessEngineConnLaunchBuilder) builder) + .setEngineConnResourceGenerator(engineConnResourceGenerator); + } + builder.setBuildRequest(engineBuildRequest); + return builder; + } + + @Override + @Receiver + public EngineConnLaunchRequest createEngineConnLaunchRequest( + EngineConnBuildRequest engineBuildRequest) { + final Optional engineTypeOption = + engineBuildRequest.labels().stream() + .filter(label -> label instanceof EngineTypeLabel) + .map(label -> (EngineTypeLabel) label) + .findFirst(); + + if (!engineTypeOption.isPresent()) { + throw new EngineConnPluginErrorException( + EngineconnCoreErrorCodeSummary.ETL_REQUESTED.getErrorCode(), + EngineconnCoreErrorCodeSummary.ETL_REQUESTED.getErrorDesc()); + } + + final EngineTypeLabel engineTypeLabel = engineTypeOption.get(); + return LinkisUtils.tryCatch( + () -> getEngineLaunchBuilder(engineTypeLabel, engineBuildRequest).buildEngineConn(), + (Throwable t) -> { + logger.error( + String.format( + "Failed to createEngineConnLaunchRequest(%s)", engineBuildRequest.ticketId()), + t); + throw new EngineConnPluginErrorException( + EngineconnCoreErrorCodeSummary.FAILED_CREATE_ELR.getErrorCode(), + String.format( + "%s, %s", + EngineconnCoreErrorCodeSummary.FAILED_CREATE_ELR.getErrorDesc(), + ExceptionUtils.getRootCauseMessage(t))); + }); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceFactoryService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceFactoryService.java new file mode 100644 index 0000000000..2c0496c071 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceFactoryService.java @@ -0,0 +1,80 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.engineplugin.server.loader.EngineConnPluginsLoaderFactory; +import org.apache.linkis.manager.am.exception.AMErrorCode; +import org.apache.linkis.manager.am.exception.AMErrorException; +import org.apache.linkis.manager.common.entity.resource.NodeResource; +import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginErrorException; +import org.apache.linkis.manager.engineplugin.common.loader.entity.EngineConnPluginInstance; +import org.apache.linkis.manager.engineplugin.common.resource.EngineResourceFactory; +import org.apache.linkis.manager.engineplugin.common.resource.EngineResourceRequest; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.rpc.message.annotation.Receiver; + +import org.springframework.stereotype.Component; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary.ETL_REQUESTED; + +@Component +public class DefaultEngineConnResourceFactoryService implements EngineConnResourceFactoryService { + + private static final Logger logger = + LoggerFactory.getLogger(DefaultEngineConnResourceFactoryService.class); + + @Override + public EngineResourceFactory getResourceFactoryBy(EngineTypeLabel engineType) { + final EngineConnPluginInstance engineConnPluginInstance; + try { + engineConnPluginInstance = + EngineConnPluginsLoaderFactory.getEngineConnPluginsLoader() + .getEngineConnPlugin(engineType); + } catch (Exception e) { + logger.warn("getResourceFactory failed engineType:{}", engineType, e); + throw new AMErrorException( + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorCode(), + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorDesc()); + } + return engineConnPluginInstance.plugin().getEngineResourceFactory(); + } + + @Override + @Receiver + public NodeResource createEngineResource(final EngineResourceRequest engineResourceRequest) { + logger.info(String.format("To invoke createEngineResource %s", engineResourceRequest)); + final Optional engineTypeOption = + engineResourceRequest.labels().stream() + .filter(label -> label instanceof EngineTypeLabel) + .map(label -> (EngineTypeLabel) label) + .findFirst(); + + if (!engineTypeOption.isPresent()) { + throw new EngineConnPluginErrorException( + ETL_REQUESTED.getErrorCode(), ETL_REQUESTED.getErrorDesc()); + } + + final EngineTypeLabel engineTypeLabel = engineTypeOption.get(); + return getResourceFactoryBy(engineTypeLabel).createEngineResource(engineResourceRequest); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceService.java new file mode 100644 index 0000000000..a33b1afde8 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/DefaultEngineConnResourceService.java @@ -0,0 +1,351 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.bml.client.BmlClient; +import org.apache.linkis.bml.client.BmlClientFactory; +import org.apache.linkis.bml.protocol.BmlUpdateResponse; +import org.apache.linkis.bml.protocol.BmlUploadResponse; +import org.apache.linkis.common.utils.Utils; +import org.apache.linkis.engineplugin.server.conf.EngineConnPluginConfiguration; +import org.apache.linkis.engineplugin.server.dao.EngineConnBmlResourceDao; +import org.apache.linkis.engineplugin.server.entity.EngineConnBmlResource; +import org.apache.linkis.engineplugin.server.localize.EngineConnBmlResourceGenerator; +import org.apache.linkis.engineplugin.server.localize.EngineConnLocalizeResource; +import org.apache.linkis.manager.common.protocol.bml.BmlResource; +import org.apache.linkis.manager.common.protocol.bml.BmlResource.BmlResourceVisibility; +import org.apache.linkis.manager.engineplugin.common.exception.EngineConnPluginErrorException; +import org.apache.linkis.manager.engineplugin.common.launch.process.EngineConnResource; +import org.apache.linkis.manager.engineplugin.common.launch.process.LaunchConstants; +import org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary; +import org.apache.linkis.rpc.message.annotation.Receiver; + +import org.apache.commons.lang3.StringUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +import java.text.MessageFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.manager.engineplugin.errorcode.EngineconnCoreErrorCodeSummary.EN_PLUGIN_MATERIAL_SOURCE_EXCEPTION; + +@Component +public class DefaultEngineConnResourceService extends EngineConnResourceService { + private static final Logger logger = + LoggerFactory.getLogger(DefaultEngineConnResourceService.class); + + @Autowired private EngineConnBmlResourceGenerator engineConnBmlResourceGenerator; + + @Autowired private EngineConnBmlResourceDao engineConnBmlResourceDao; + + private final BmlClient bmlClient = BmlClientFactory.createBmlClient(); + private boolean isRefreshing = false; + + @PostConstruct + @Override + public void init() { + if ((boolean) EngineConnPluginConfiguration.ENGINE_CONN_DIST_LOAD_ENABLE.getValue()) { + logger.info("Start to refresh all engineconn plugins when inited."); + refreshAll(false, false); + } + } + + private BmlResource uploadToBml(final EngineConnLocalizeResource localizeResource) { + final BmlUploadResponse response = + bmlClient.uploadResource( + Utils.getJvmUser(), localizeResource.fileName(), localizeResource.getFileInputStream()); + final BmlResource bmlResource = new BmlResource(); + bmlResource.setResourceId(response.resourceId()); + bmlResource.setVersion(response.version()); + return bmlResource; + } + + private BmlResource uploadToBml( + final EngineConnLocalizeResource localizeResource, final String resourceId) { + final BmlUpdateResponse response = + bmlClient.updateResource( + Utils.getJvmUser(), + resourceId, + localizeResource.fileName(), + localizeResource.getFileInputStream()); + final BmlResource bmlResource = new BmlResource(); + bmlResource.setResourceId(response.resourceId()); + bmlResource.setVersion(response.version()); + return bmlResource; + } + + @Override + public void refreshAll(boolean iswait, boolean force) { + if (!isRefreshing) { + synchronized (this) { + if (!isRefreshing) { + + final Runnable refreshTask = + new Runnable() { + @Override + public void run() { + isRefreshing = true; + logger.info("Try to initialize the dist resources of all EngineConns. "); + String[] engineConnTypeList = + engineConnBmlResourceGenerator.getEngineConnTypeListFromDisk(); + for (String engineConnType : engineConnTypeList) { + try { + logger.info( + "Try to initialize all versions of {}EngineConn.", engineConnType); + Map version2Localize = + engineConnBmlResourceGenerator.generate(engineConnType); + for (Map.Entry entry : + version2Localize.entrySet()) { + logger.info( + "Try to initialize {}EngineConn-{}.", engineConnType, entry.getKey()); + refresh(entry.getValue(), engineConnType, entry.getKey(), force); + } + + } catch (Exception t) { + if (!iswait + && EngineConnPluginConfiguration.ENABLED_BML_UPLOAD_FAILED_EXIT + .getValue()) { + logger.error("Failed to upload engine conn to bml, now exit!", t); + System.exit(1); + } + logger.error("Failed to upload engine conn to bml", t); + } + } + isRefreshing = false; + } + }; + Future future = Utils.defaultScheduler().submit(refreshTask); + + if (iswait) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + logger.info("DefaultEngineConnResourceService refreshTask execution failed", e); + } + } else { + logger.info("DefaultEngineConnResourceService IsRefreshing EngineConns..."); + } + } + } + } + } + + @Receiver + public boolean refreshAll(final RefreshAllEngineConnResourceRequest engineConnRefreshAllRequest) { + logger.info("Start to refresh all engineconn plugins."); + refreshAll(true, false); + return true; + } + + @Receiver + @Override + public boolean refresh( + final RefreshEngineConnResourceRequest engineConnRefreshRequest, final boolean force) { + final String engineConnType = engineConnRefreshRequest.getEngineConnType(); + final String version = engineConnRefreshRequest.getVersion(); + if ("*".equals(version) || StringUtils.isEmpty(version)) { + logger.info("Try to refresh all versions of {}EngineConn.", engineConnType); + Map version2Localize = + engineConnBmlResourceGenerator.generate(engineConnType); + for (Map.Entry entry : version2Localize.entrySet()) { + logger.info("Try to initialize {}EngineConn-{}.", engineConnType, entry.getKey()); + refresh(entry.getValue(), engineConnType, entry.getKey(), force); + } + + } else { + logger.info("Try to refresh {}EngineConn-{}.", engineConnType, version); + EngineConnLocalizeResource[] localize = + engineConnBmlResourceGenerator.generate(engineConnType, version); + refresh(localize, engineConnType, version, force); + } + return true; + } + + private void refresh( + final EngineConnLocalizeResource[] localize, + final String engineConnType, + final String version, + final boolean force) { + final List engineConnBmlResources = + engineConnBmlResourceDao.getAllEngineConnBmlResource(engineConnType, version); + + if (Stream.of(localize) + .filter( + localizeResource -> + StringUtils.equals( + LaunchConstants.ENGINE_CONN_CONF_DIR_NAME() + ".zip", + localizeResource.fileName()) + || StringUtils.equals( + LaunchConstants.ENGINE_CONN_LIB_DIR_NAME() + ".zip", + localizeResource.fileName())) + .count() + < 2) { + + throw new EngineConnPluginErrorException( + EngineconnCoreErrorCodeSummary.LIB_CONF_DIR_NECESSARY.getErrorCode(), + MessageFormat.format( + EngineconnCoreErrorCodeSummary.LIB_CONF_DIR_NECESSARY.getErrorDesc(), + engineConnType)); + } + + for (EngineConnLocalizeResource localizeResource : localize) { + + Optional resource = + engineConnBmlResources.stream() + .filter(r -> r.getFileName().equals(localizeResource.fileName())) + .findFirst(); + if (!resource.isPresent()) { + logger.info( + "Ready to upload a new bmlResource for {}EngineConn-{}. path: {}", + engineConnType, + version, + localizeResource.fileName()); + final BmlResource bmlResource = uploadToBml(localizeResource); + final EngineConnBmlResource engineConnBmlResource = new EngineConnBmlResource(); + engineConnBmlResource.setBmlResourceId(bmlResource.getResourceId()); + engineConnBmlResource.setBmlResourceVersion(bmlResource.getVersion()); + engineConnBmlResource.setCreateTime(new Date()); + engineConnBmlResource.setLastUpdateTime(new Date()); + engineConnBmlResource.setEngineConnType(engineConnType); + engineConnBmlResource.setFileName(localizeResource.fileName()); + engineConnBmlResource.setFileSize(localizeResource.fileSize()); + engineConnBmlResource.setLastModified(localizeResource.lastModified()); + engineConnBmlResource.setVersion(version); + engineConnBmlResourceDao.save(engineConnBmlResource); + } else { + boolean isChanged = + resource.get().getFileSize() != localizeResource.fileSize() + || resource.get().getLastModified() != localizeResource.lastModified(); + + if (isChanged || (!isChanged && force)) { + if (!isChanged && force) { + logger.info( + "The file has no change in {}EngineConn-{}, path: {}, but force to refresh", + engineConnType, + version, + localizeResource.fileName()); + } + logger.info( + "Ready to upload a refreshed bmlResource for {}EngineConn-{}. path: {}", + engineConnType, + version, + localizeResource.fileName()); + final EngineConnBmlResource engineConnBmlResource = resource.get(); + final BmlResource bmlResource = + uploadToBml(localizeResource, engineConnBmlResource.getBmlResourceId()); + engineConnBmlResource.setBmlResourceVersion(bmlResource.getVersion()); + engineConnBmlResource.setLastUpdateTime(new Date()); + engineConnBmlResource.setFileSize(localizeResource.fileSize()); + engineConnBmlResource.setLastModified(localizeResource.lastModified()); + engineConnBmlResourceDao.update(engineConnBmlResource); + } else { + logger.info( + "The file has no change in {}EngineConn-{}, path: {}", + engineConnType, + version, + localizeResource.fileName()); + } + } + } + } + + @Receiver + @Override + public EngineConnResource getEngineConnBMLResources( + final GetEngineConnResourceRequest engineConnBMLResourceRequest) { + final String engineConnType = engineConnBMLResourceRequest.getEngineConnType(); + final String version = engineConnBMLResourceRequest.getVersion(); + + List engineConnBmlResources = + engineConnBmlResourceDao.getAllEngineConnBmlResource(engineConnType, version); + if (engineConnBmlResources.size() == 0 + && (boolean) EngineConnPluginConfiguration.EC_BML_VERSION_MAY_WITH_PREFIX_V.getValue()) { + logger.info("Try to get engine conn bml resource with prefex v"); + engineConnBmlResourceDao.getAllEngineConnBmlResource(engineConnType, "v" + version); + } + + Optional confBmlResourceMap = + engineConnBmlResources.stream() + .filter( + r -> r.getFileName().equals(LaunchConstants.ENGINE_CONN_CONF_DIR_NAME() + ".zip")) + .map(this::parseToBmlResource) + .findFirst(); + Optional libBmlResourceMap = + engineConnBmlResources.stream() + .filter( + r -> r.getFileName().equals(LaunchConstants.ENGINE_CONN_LIB_DIR_NAME() + ".zip")) + .map(this::parseToBmlResource) + .findFirst(); + + if (!confBmlResourceMap.isPresent() || !libBmlResourceMap.isPresent()) { + throw new EngineConnPluginErrorException( + EN_PLUGIN_MATERIAL_SOURCE_EXCEPTION.getErrorCode(), + EN_PLUGIN_MATERIAL_SOURCE_EXCEPTION.getErrorDesc()); + } + final BmlResource confBmlResource = confBmlResourceMap.get(); + final BmlResource libBmlResource = libBmlResourceMap.get(); + BmlResource[] otherBmlResources = + engineConnBmlResources.stream() + .filter( + r -> + !r.getFileName().equals(LaunchConstants.ENGINE_CONN_CONF_DIR_NAME() + ".zip") + || r.getFileName() + .equals(LaunchConstants.ENGINE_CONN_LIB_DIR_NAME() + ".zip")) + .map(this::parseToBmlResource) + .toArray(BmlResource[]::new); + + return new EngineConnResource() { + @Override + public BmlResource getConfBmlResource() { + return confBmlResource; + } + + @Override + public BmlResource getLibBmlResource() { + return libBmlResource; + } + + @Override + public BmlResource[] getOtherBmlResources() { + return otherBmlResources; + } + }; + } + + private BmlResource parseToBmlResource(final EngineConnBmlResource engineConnBmlResource) { + final BmlResource bmlResource = new BmlResource(); + bmlResource.setFileName(engineConnBmlResource.getFileName()); + bmlResource.setOwner(Utils.getJvmUser()); + bmlResource.setResourceId(engineConnBmlResource.getBmlResourceId()); + bmlResource.setVersion(engineConnBmlResource.getBmlResourceVersion()); + bmlResource.setVisibility(BmlResourceVisibility.Public); + return bmlResource; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.java similarity index 73% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.java index 92f8c27edd..370fdbee13 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnLaunchService.java @@ -15,17 +15,12 @@ * limitations under the License. */ -package org.apache.linkis.engineplugin.server.service +package org.apache.linkis.engineplugin.server.service; -import org.apache.linkis.manager.engineplugin.common.launch.entity.{ - EngineConnBuildRequest, - EngineConnLaunchRequest -} - -trait EngineConnLaunchService { +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnBuildRequest; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnLaunchRequest; - def createEngineConnLaunchRequest( - engineBuildRequest: EngineConnBuildRequest - ): EngineConnLaunchRequest +public interface EngineConnLaunchService { + EngineConnLaunchRequest createEngineConnLaunchRequest(EngineConnBuildRequest engineBuildRequest); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.java similarity index 67% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.java index 35be84e849..6fa6db5271 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceFactoryService.java @@ -15,19 +15,16 @@ * limitations under the License. */ -package org.apache.linkis.engineplugin.server.service +package org.apache.linkis.engineplugin.server.service; -import org.apache.linkis.manager.common.entity.resource.NodeResource -import org.apache.linkis.manager.engineplugin.common.resource.{ - EngineResourceFactory, - EngineResourceRequest -} -import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel - -trait EngineConnResourceFactoryService { +import org.apache.linkis.manager.common.entity.resource.NodeResource; +import org.apache.linkis.manager.engineplugin.common.resource.EngineResourceFactory; +import org.apache.linkis.manager.engineplugin.common.resource.EngineResourceRequest; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; - def getResourceFactoryBy(engineType: EngineTypeLabel): EngineResourceFactory +public interface EngineConnResourceFactoryService { - def createEngineResource(engineResourceRequest: EngineResourceRequest): NodeResource + EngineResourceFactory getResourceFactoryBy(EngineTypeLabel engineType); + NodeResource createEngineResource(EngineResourceRequest engineResourceRequest); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceRequest.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceRequest.java new file mode 100644 index 0000000000..62f7aea661 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceRequest.java @@ -0,0 +1,53 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.protocol.message.RequestMethod; +import org.apache.linkis.protocol.message.RequestProtocol; + +public abstract class EngineConnResourceRequest implements RequestProtocol, RequestMethod { + + private String engineConnType; + private String version; + + private boolean force; + + public String getEngineConnType() { + return engineConnType; + } + + public void setEngineConnType(String engineConnType) { + this.engineConnType = engineConnType; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public boolean getForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceService.java new file mode 100644 index 0000000000..5f2fb6cf69 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/EngineConnResourceService.java @@ -0,0 +1,43 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.manager.engineplugin.common.launch.process.EngineConnResource; +import org.apache.linkis.manager.engineplugin.common.launch.process.EngineConnResourceGenerator; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; + +public abstract class EngineConnResourceService implements EngineConnResourceGenerator { + + public abstract void init(); + + public abstract void refreshAll(boolean wait, boolean force); + + public abstract boolean refresh( + RefreshEngineConnResourceRequest engineConnRefreshRequest, boolean force); + + public abstract EngineConnResource getEngineConnBMLResources( + GetEngineConnResourceRequest engineConnBMLResourceRequest); + + @Override + public EngineConnResource getEngineConnBMLResources(EngineTypeLabel engineTypeLabel) { + GetEngineConnResourceRequest engineConnBMLResourceRequest = new GetEngineConnResourceRequest(); + engineConnBMLResourceRequest.setEngineConnType(engineTypeLabel.getEngineType()); + engineConnBMLResourceRequest.setVersion(engineTypeLabel.getVersion()); + return getEngineConnBMLResources(engineConnBMLResourceRequest); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/GetEngineConnResourceRequest.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/GetEngineConnResourceRequest.java new file mode 100644 index 0000000000..046a0dd7ec --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/GetEngineConnResourceRequest.java @@ -0,0 +1,25 @@ +/* + * 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.linkis.engineplugin.server.service; + +public class GetEngineConnResourceRequest extends EngineConnResourceRequest { + @Override + public String method() { + return "/enginePlugin/engineConn/getResource"; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshAllEngineConnResourceRequest.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshAllEngineConnResourceRequest.java new file mode 100644 index 0000000000..6bd41d2599 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshAllEngineConnResourceRequest.java @@ -0,0 +1,28 @@ +/* + * 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.linkis.engineplugin.server.service; + +import org.apache.linkis.protocol.message.RequestMethod; +import org.apache.linkis.protocol.message.RequestProtocol; + +public class RefreshAllEngineConnResourceRequest implements RequestProtocol, RequestMethod { + @Override + public String method() { + return "/enginePlugin/engineConn/refreshAll"; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshEngineConnResourceRequest.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshEngineConnResourceRequest.java new file mode 100644 index 0000000000..f518a72059 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/RefreshEngineConnResourceRequest.java @@ -0,0 +1,25 @@ +/* + * 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.linkis.engineplugin.server.service; + +public class RefreshEngineConnResourceRequest extends EngineConnResourceRequest { + @Override + public String method() { + return "/enginePlugin/engineConn/refresh"; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/impl/EnginePluginAdminServiceImpl.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/impl/EnginePluginAdminServiceImpl.java index 803151d534..069afd4f1b 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/impl/EnginePluginAdminServiceImpl.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/engineplugin/server/service/impl/EnginePluginAdminServiceImpl.java @@ -94,7 +94,12 @@ public void deleteEnginePluginBML(String ecType, String version, String username log.info("file {} delete success", ecType); } } catch (Exception e) { - e.printStackTrace(); + log.warn( + "deleteEnginePluginBML failed ecType:[{}] version:[{}] username:[{}]", + ecType, + version, + username, + e); } } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/AMConfiguration.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/AMConfiguration.java new file mode 100644 index 0000000000..d916387d29 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/AMConfiguration.java @@ -0,0 +1,125 @@ +/* + * 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.linkis.manager.am.conf; + +import org.apache.linkis.common.conf.CommonVars; +import org.apache.linkis.common.conf.TimeType; +import org.apache.linkis.common.utils.Utils; +import org.apache.linkis.manager.common.entity.enumeration.MaintainType; + +import java.util.Arrays; +import java.util.Optional; + +public class AMConfiguration { + + public static final CommonVars ECM_ADMIN_OPERATIONS = + CommonVars.apply("wds.linkis.governance.admin.operations", ""); + + public static final CommonVars ENGINE_START_MAX_TIME = + CommonVars.apply("wds.linkis.manager.am.engine.start.max.time", new TimeType("11m")); + + public static final CommonVars ENGINE_CONN_START_REST_MAX_WAIT_TIME = + CommonVars.apply("wds.linkis.manager.am.engine.rest.start.max.time", new TimeType("40s")); + + public static final CommonVars ENGINE_REUSE_MAX_TIME = + CommonVars.apply("wds.linkis.manager.am.engine.reuse.max.time", new TimeType("5m")); + + public static final CommonVars ENGINE_REUSE_COUNT_LIMIT = + CommonVars.apply("wds.linkis.manager.am.engine.reuse.count.limit", 2); + + public static final CommonVars NODE_STATUS_HEARTBEAT_TIME = + CommonVars.apply("wds.linkis.manager.am.node.heartbeat", new TimeType("3m")); + + public static final CommonVars NODE_HEARTBEAT_MAX_UPDATE_TIME = + CommonVars.apply("wds.linkis.manager.am.node.heartbeat", new TimeType("5m")); + + public static final CommonVars DEFAULT_NODE_OWNER = + CommonVars.apply("wds.linkis.manager.am.default.node.owner", "hadoop"); + + public static final CommonVars STOP_ENGINE_WAIT = + CommonVars.apply("wds.linkis.manager.am.stop.engine.wait", new TimeType("5m")); + + public static final CommonVars STOP_EM_WAIT = + CommonVars.apply("wds.linkis.manager.am.stop.em.wait", new TimeType("5m")); + + public static final CommonVars EM_LABEL_INIT_WAIT = + CommonVars.apply("wds.linkis.manager.am.em.label.init.wait", new TimeType("5m")); + + public static final CommonVars EM_NEW_WAIT_MILLS = + CommonVars.apply("wds.linkis.manager.am.em.new.wait.mills", 1000 * 60L); + + public static final CommonVars ENGINECONN_DEBUG_ENABLED = + CommonVars.apply("wds.linkis.engineconn.debug.mode.enable", false); + + public static final CommonVars MULTI_USER_ENGINE_TYPES = + CommonVars.apply( + "wds.linkis.multi.user.engine.types", "jdbc,es,presto,io_file,appconn,openlookeng,trino"); + + public static final CommonVars ALLOW_BATCH_KILL_ENGINE_TYPES = + CommonVars.apply("wds.linkis.allow.batch.kill.engine.types", "spark,hive,python"); + + public static final CommonVars MULTI_USER_ENGINE_USER = + CommonVars.apply("wds.linkis.multi.user.engine.user", getDefaultMultiEngineUser()); + + public static final CommonVars ENGINE_LOCKER_MAX_TIME = + CommonVars.apply("wds.linkis.manager.am.engine.locker.max.time", 1000 * 60 * 5); + + public static final CommonVars AM_CAN_RETRY_LOGS = + CommonVars.apply( + "wds.linkis.manager.am.can.retry.logs", "already in use;Cannot allocate memory"); + + public static final int ASK_ENGINE_ASYNC_MAX_THREAD_SIZE = + CommonVars.apply("wds.linkis.ecm.launch.max.thread.size", 200).getValue(); + + public static final int ASYNC_STOP_ENGINE_MAX_THREAD_SIZE = + CommonVars.apply("wds.linkis.async.stop.engine.size", 20).getValue(); + + public static final CommonVars EC_MAINTAIN_TIME_STR = + CommonVars.apply("wds.linkis.ec.maintain.time.key", MaintainType.Default.toString()); + + public static final int EC_MAINTAIN_WORK_START_TIME = + CommonVars.apply("wds.linkis.ec.maintain.time.work.start.time", 8).getValue(); + + public static final int EC_MAINTAIN_WORK_END_TIME = + CommonVars.apply("wds.linkis.ec.maintain.time.work.end.time", 19).getValue(); + + public static final Boolean NODE_SELECT_HOTSPOT_EXCLUSION_RULE = + CommonVars.apply("linkis.node.select.hotspot.exclusion.rule.enable", true).getValue(); + + public static String getDefaultMultiEngineUser() { + String jvmUser = Utils.getJvmUser(); + return String.format( + "{jdbc:\"%s\", es: \"%s\", presto:\"%s\", appconn:\"%s\", openlookeng:\"%s\", trino:\"%s\", io_file:\"root\"}", + jvmUser, jvmUser, jvmUser, jvmUser, jvmUser, jvmUser); + } + + public static boolean isMultiUserEngine(String engineType) { + String[] multiUserEngine = AMConfiguration.MULTI_USER_ENGINE_TYPES.getValue().split(","); + Optional findResult = + Arrays.stream(multiUserEngine).filter(e -> e.equalsIgnoreCase(engineType)).findFirst(); + return findResult.isPresent(); + } + + public static boolean isAllowKilledEngineType(String engineType) { + String[] allowBatchKillEngine = + AMConfiguration.ALLOW_BATCH_KILL_ENGINE_TYPES.getValue().split(","); + Optional findResult = + Arrays.stream(allowBatchKillEngine).filter(e -> e.equalsIgnoreCase(engineType)).findFirst(); + return findResult.isPresent(); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ApplicationManagerSpringConfiguration.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ApplicationManagerSpringConfiguration.java new file mode 100644 index 0000000000..96d28a185b --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ApplicationManagerSpringConfiguration.java @@ -0,0 +1,32 @@ +/* + * 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.linkis.manager.am.conf; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ApplicationManagerSpringConfiguration { + + @ConditionalOnMissingBean + @Bean + public EngineConnConfigurationService getDefaultEngineConnConfigurationService() { + return new DefaultEngineConnConfigurationService(); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ConfigurationMapCache.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ConfigurationMapCache.java new file mode 100644 index 0000000000..039704351e --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ConfigurationMapCache.java @@ -0,0 +1,69 @@ +/* + * 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.linkis.manager.am.conf; + +import org.apache.linkis.common.conf.Configuration; +import org.apache.linkis.governance.common.protocol.conf.*; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.manager.label.entity.engine.UserCreatorLabel; +import org.apache.linkis.protocol.CacheableProtocol; +import org.apache.linkis.rpc.RPCMapCache; + +import java.util.Map; + +import scala.Tuple2; + +public class ConfigurationMapCache { + + public static RPCMapCache globalMapCache = + new RPCMapCache( + Configuration.CLOUD_CONSOLE_CONFIGURATION_SPRING_APPLICATION_NAME().getValue()) { + @Override + public CacheableProtocol createRequest(UserCreatorLabel userCreatorLabel) { + return new RequestQueryGlobalConfig(userCreatorLabel.getUser()); + } + + @Override + public Map createMap(Object any) { + if (any instanceof ResponseQueryConfig) { + return ((ResponseQueryConfig) any).getKeyAndValue(); + } + return null; + } + }; + + public static RPCMapCache, String, String> + engineMapCache = + new RPCMapCache, String, String>( + Configuration.CLOUD_CONSOLE_CONFIGURATION_SPRING_APPLICATION_NAME().getValue()) { + @Override + public CacheableProtocol createRequest( + Tuple2 labelTuple) { + return new RequestQueryEngineConfigWithGlobalConfig( + labelTuple._1(), labelTuple._2(), null); + } + + @Override + public Map createMap(Object any) { + if (any instanceof ResponseQueryConfig) { + return ((ResponseQueryConfig) any).getKeyAndValue(); + } + return null; + } + }; +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/DefaultEngineConnConfigurationService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/DefaultEngineConnConfigurationService.java new file mode 100644 index 0000000000..3575491087 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/DefaultEngineConnConfigurationService.java @@ -0,0 +1,72 @@ +/* + * 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.linkis.manager.am.conf; + +import org.apache.linkis.manager.am.util.LinkisUtils; +import org.apache.linkis.manager.label.entity.Label; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.manager.label.entity.engine.UserCreatorLabel; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import scala.Tuple2; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class DefaultEngineConnConfigurationService implements EngineConnConfigurationService { + + private static final Logger logger = + LoggerFactory.getLogger(DefaultEngineConnConfigurationService.class); + + @Override + public Map getConsoleConfiguration(List> labelList) { + Map properties = new HashMap<>(); + + Optional userCreatorLabelOption = + labelList.stream() + .filter(l -> l instanceof UserCreatorLabel) + .map(l -> (UserCreatorLabel) l) + .findFirst(); + + Optional engineTypeLabelOption = + labelList.stream() + .filter(l -> l instanceof EngineTypeLabel) + .map(l -> (EngineTypeLabel) l) + .findFirst(); + userCreatorLabelOption.ifPresent( + userCreatorLabel -> { + engineTypeLabelOption.ifPresent( + engineTypeLabel -> { + Map engineConfig = + LinkisUtils.tryAndWarn( + () -> + ConfigurationMapCache.engineMapCache.getCacheMap( + new Tuple2(userCreatorLabel, engineTypeLabel)), + logger); + if (engineConfig != null) { + properties.putAll(engineConfig); + } + }); + }); + return properties; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/EngineConnConfigurationService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/EngineConnConfigurationService.java new file mode 100644 index 0000000000..2d2d01d057 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/EngineConnConfigurationService.java @@ -0,0 +1,28 @@ +/* + * 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.linkis.manager.am.conf; + +import org.apache.linkis.manager.label.entity.Label; + +import java.util.List; +import java.util.Map; + +public interface EngineConnConfigurationService { + + Map getConsoleConfiguration(List> labelList); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ManagerMonitorConf.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ManagerMonitorConf.java new file mode 100644 index 0000000000..c3a35f7921 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/conf/ManagerMonitorConf.java @@ -0,0 +1,45 @@ +/* + * 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.linkis.manager.am.conf; + +import org.apache.linkis.common.conf.CommonVars; +import org.apache.linkis.common.conf.TimeType; + +public class ManagerMonitorConf { + + public static final CommonVars NODE_MAX_CREATE_TIME = + CommonVars.apply("wds.linkis.manager.am.node.create.time", new TimeType("12m")); + + public static final CommonVars NODE_HEARTBEAT_MAX_UPDATE_TIME = + CommonVars.apply("wds.linkis.manager.am.node.heartbeat", new TimeType("12m")); + + public static final CommonVars ENGINE_KILL_TIMEOUT = + CommonVars.apply("wds.linkis.manager.am.engine.kill.timeout", new TimeType("2m")); + + public static final CommonVars EM_KILL_TIMEOUT = + CommonVars.apply("wds.linkis.manager.am.em.kill.timeout", new TimeType("2m")); + + public static final CommonVars MANAGER_MONITOR_ASYNC_POLL_SIZE = + CommonVars.apply("wds.linkis.manager.monitor.async.poll.size", 5); + + public static final CommonVars MONITOR_SWITCH_ON = + CommonVars.apply("wds.linkis.manager.am.monitor.switch.on", true); + + public static final CommonVars ECM_HEARTBEAT_MAX_UPDATE_TIME = + CommonVars.apply("wds.linkis.manager.am.ecm.heartbeat", new TimeType("5m")); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/converter/DefaultMetricsConverter.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/converter/DefaultMetricsConverter.java new file mode 100644 index 0000000000..4736433ada --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/converter/DefaultMetricsConverter.java @@ -0,0 +1,140 @@ +/* + * 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.linkis.manager.am.converter; + +import org.apache.linkis.manager.common.entity.enumeration.NodeStatus; +import org.apache.linkis.manager.common.entity.metrics.NodeHealthyInfo; +import org.apache.linkis.manager.common.entity.metrics.NodeMetrics; +import org.apache.linkis.manager.common.entity.metrics.NodeOverLoadInfo; +import org.apache.linkis.manager.common.entity.metrics.NodeTaskInfo; +import org.apache.linkis.manager.common.entity.node.AMNode; +import org.apache.linkis.manager.service.common.metrics.MetricsConverter; +import org.apache.linkis.server.BDPJettyServerHelper; + +import org.apache.commons.lang3.StringUtils; + +import org.springframework.stereotype.Component; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class DefaultMetricsConverter implements MetricsConverter { + + private static final Logger logger = LoggerFactory.getLogger(DefaultMetricsConverter.class); + + @Override + public NodeTaskInfo parseTaskInfo(NodeMetrics nodeMetrics) { + String msg = nodeMetrics.getHeartBeatMsg(); + if (StringUtils.isNotBlank(msg)) { + try { + JsonNode jsonNode = BDPJettyServerHelper.jacksonJson().readTree(msg); + if (jsonNode != null && jsonNode.has("taskInfo")) { + NodeTaskInfo taskInfo = + BDPJettyServerHelper.jacksonJson() + .readValue(jsonNode.get("taskInfo").asText(), NodeTaskInfo.class); + return taskInfo; + } + } catch (IOException e) { + logger.error("parse task info failed", e); + } + } + return null; + } + + @Override + public NodeHealthyInfo parseHealthyInfo(NodeMetrics nodeMetrics) { + String healthyInfo = nodeMetrics.getHealthy(); + if (StringUtils.isNotBlank(healthyInfo)) { + try { + return BDPJettyServerHelper.jacksonJson().readValue(healthyInfo, NodeHealthyInfo.class); + } catch (IOException e) { + logger.error("parse healthy info failed", e); + } + } + return null; + } + + @Override + public NodeOverLoadInfo parseOverLoadInfo(NodeMetrics nodeMetrics) { + String overLoad = nodeMetrics.getOverLoad(); + if (StringUtils.isNotBlank(overLoad)) { + try { + return BDPJettyServerHelper.jacksonJson().readValue(overLoad, NodeOverLoadInfo.class); + } catch (IOException e) { + logger.error("parse over load info failed", e); + } + } + return null; + } + + @Override + public NodeStatus parseStatus(NodeMetrics nodeMetrics) { + return NodeStatus.values()[nodeMetrics.getStatus()]; + } + + @Override + public String convertTaskInfo(NodeTaskInfo nodeTaskInfo) { + try { + return BDPJettyServerHelper.jacksonJson().writeValueAsString(nodeTaskInfo); + } catch (JsonProcessingException e) { + logger.error("convert task info failed", e); + } + return null; + } + + @Override + public String convertHealthyInfo(NodeHealthyInfo nodeHealthyInfo) { + try { + return BDPJettyServerHelper.jacksonJson().writeValueAsString(nodeHealthyInfo); + } catch (JsonProcessingException e) { + logger.error("convert healthy info failed", e); + } + return null; + } + + @Override + public String convertOverLoadInfo(NodeOverLoadInfo nodeOverLoadInfo) { + try { + return BDPJettyServerHelper.jacksonJson().writeValueAsString(nodeOverLoadInfo); + } catch (JsonProcessingException e) { + logger.error("convert over load info failed", e); + } + return null; + } + + @Override + public int convertStatus(NodeStatus nodeStatus) { + return nodeStatus.ordinal(); + } + + @Override + public AMNode fillMetricsToNode(AMNode amNode, NodeMetrics metrics) { + if (metrics == null) return amNode; + amNode.setNodeStatus(parseStatus(metrics)); + amNode.setNodeTaskInfo(parseTaskInfo(metrics)); + amNode.setNodeHealthyInfo(parseHealthyInfo(metrics)); + amNode.setNodeOverLoadInfo(parseOverLoadInfo(metrics)); + amNode.setUpdateTime(metrics.getUpdateTime()); + return amNode; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/exception/AMErrorException.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/exception/AMErrorException.java index 727fcc3133..4f3badbb9a 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/exception/AMErrorException.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/exception/AMErrorException.java @@ -17,9 +17,10 @@ package org.apache.linkis.manager.am.exception; -import org.apache.linkis.common.exception.ErrorException; +import org.apache.linkis.common.exception.ExceptionLevel; +import org.apache.linkis.common.exception.LinkisRuntimeException; -public class AMErrorException extends ErrorException { +public class AMErrorException extends LinkisRuntimeException { public AMErrorException(int errCode, String desc) { super(errCode, desc); @@ -29,4 +30,9 @@ public AMErrorException(int errCode, String desc, Throwable t) { this(errCode, desc); this.initCause(t); } + + @Override + public ExceptionLevel getLevel() { + return ExceptionLevel.ERROR; + } } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelChecker.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelChecker.java new file mode 100644 index 0000000000..a0928db981 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelChecker.java @@ -0,0 +1,56 @@ +/* + * 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.linkis.manager.am.label; + +import org.apache.linkis.manager.label.entity.Label; +import org.apache.linkis.manager.label.entity.em.EMInstanceLabel; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.manager.label.entity.engine.UserCreatorLabel; +import org.apache.linkis.manager.service.common.label.LabelChecker; + +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +class AMLabelChecker implements LabelChecker { + + @Override + public boolean checkEngineLabel(List> labelList) { + return checkCorrespondingLabel(labelList, EngineTypeLabel.class, UserCreatorLabel.class); + } + + @Override + public boolean checkEMLabel(List> labelList) { + return checkCorrespondingLabel(labelList, EMInstanceLabel.class); + } + + @Override + public boolean checkCorrespondingLabel(List> labelList, Class... clazz) { + // TODO: 是否需要做子类的判断 + List> classes = Arrays.asList(clazz); + return labelList.stream() + .filter(Objects::nonNull) + .map(Label::getClass) + .collect(Collectors.toList()) + .containsAll(classes); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelFilter.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelFilter.java new file mode 100644 index 0000000000..5fa8e7db12 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/AMLabelFilter.java @@ -0,0 +1,59 @@ +/* + * 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.linkis.manager.am.label; + +import org.apache.linkis.governance.common.conf.GovernanceCommonConf; +import org.apache.linkis.manager.label.entity.*; +import org.apache.linkis.manager.label.entity.node.AliasServiceInstanceLabel; +import org.apache.linkis.manager.service.common.label.LabelFilter; + +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class AMLabelFilter implements LabelFilter { + + @Override + public List> choseEngineLabel(List> labelList) { + return labelList.stream() + .filter( + label -> + label instanceof EngineNodeLabel + || (label instanceof AliasServiceInstanceLabel + && ((AliasServiceInstanceLabel) label) + .getAlias() + .equals(GovernanceCommonConf.ENGINE_CONN_SPRING_NAME().getValue()))) + .collect(Collectors.toList()); + } + + @Override + public List> choseEMLabel(List> labelList) { + return labelList.stream() + .filter( + label -> + label instanceof EMNodeLabel + || (label instanceof AliasServiceInstanceLabel + && ((AliasServiceInstanceLabel) label) + .getAlias() + .equals( + GovernanceCommonConf.ENGINE_CONN_MANAGER_SPRING_NAME().getValue()))) + .collect(Collectors.toList()); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/DefaultManagerLabelService.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/DefaultManagerLabelService.java new file mode 100644 index 0000000000..50c7e1ec6e --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/DefaultManagerLabelService.java @@ -0,0 +1,63 @@ +/* + * 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.linkis.manager.am.label; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.label.entity.Label; +import org.apache.linkis.manager.label.entity.em.EMInstanceLabel; +import org.apache.linkis.manager.label.entity.engine.EngineInstanceLabel; +import org.apache.linkis.manager.label.service.NodeLabelService; +import org.apache.linkis.manager.service.common.label.ManagerLabelService; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Service +public class DefaultManagerLabelService implements ManagerLabelService { + + private static final Logger logger = LoggerFactory.getLogger(DefaultManagerLabelService.class); + + @Autowired private NodeLabelService nodeLabelService; + + @Override + public boolean isEngine(ServiceInstance serviceInstance) { + List> labelList = nodeLabelService.getNodeLabels(serviceInstance); + return isEngine(labelList); + } + + @Override + public boolean isEM(ServiceInstance serviceInstance) { + List> labelList = nodeLabelService.getNodeLabels(serviceInstance); + boolean isEngine = labelList.stream().anyMatch(label -> label instanceof EngineInstanceLabel); + if (!isEngine) { + return labelList.stream().anyMatch(label -> label instanceof EMInstanceLabel); + } else { + return false; + } + } + + @Override + public boolean isEngine(List> labels) { + return labels.stream().anyMatch(label -> label instanceof EngineInstanceLabel); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/label/EngineReuseLabelRester.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/EngineReuseLabelChooser.java similarity index 78% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/label/EngineReuseLabelRester.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/EngineReuseLabelChooser.java index e890fab04f..edbaf638fa 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/label/EngineReuseLabelRester.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/EngineReuseLabelChooser.java @@ -15,14 +15,13 @@ * limitations under the License. */ -package org.apache.linkis.manager.am.label +package org.apache.linkis.manager.am.label; -import org.apache.linkis.manager.label.entity.Label +import org.apache.linkis.manager.label.entity.Label; -import java.util +import java.util.List; -trait EngineReuseLabelChooser { - - def chooseLabels(labelList: util.List[Label[_]]): util.List[Label[_]] +public interface EngineReuseLabelChooser { + List> chooseLabels(List> labelList); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/MultiUserEngineReuseLabelChooser.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/MultiUserEngineReuseLabelChooser.java new file mode 100644 index 0000000000..4fbe6894f4 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/label/MultiUserEngineReuseLabelChooser.java @@ -0,0 +1,104 @@ +/* + * 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.linkis.manager.am.label; + +import org.apache.linkis.manager.am.conf.AMConfiguration; +import org.apache.linkis.manager.am.exception.AMErrorCode; +import org.apache.linkis.manager.am.exception.AMErrorException; +import org.apache.linkis.manager.label.entity.Label; +import org.apache.linkis.manager.label.entity.engine.EngineTypeLabel; +import org.apache.linkis.manager.label.entity.engine.UserCreatorLabel; +import org.apache.linkis.server.BDPJettyServerHelper; + +import org.apache.commons.lang3.StringUtils; + +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static scala.collection.JavaConverters.*; + +@Component +public class MultiUserEngineReuseLabelChooser implements EngineReuseLabelChooser { + private static final Logger logger = + LoggerFactory.getLogger(MultiUserEngineReuseLabelChooser.class); + + private final String[] multiUserEngine = + AMConfiguration.MULTI_USER_ENGINE_TYPES.getValue().split(","); + private final Map userMap = getMultiUserEngineUserMap(); + + private Map getMultiUserEngineUserMap() { + String userJson = AMConfiguration.MULTI_USER_ENGINE_USER.getValue(); + if (StringUtils.isNotBlank(userJson)) { + Map userMap = BDPJettyServerHelper.gson().fromJson(userJson, Map.class); + return userMap; + } else { + throw new AMErrorException( + AMErrorCode.AM_CONF_ERROR.getErrorCode(), + String.format( + "Multi-user engine parameter configuration error, please check key %s", + AMConfiguration.MULTI_USER_ENGINE_USER.key())); + } + } + + /** + * Filter out UserCreator Label that supports multi-user engine + * + * @param labelList + * @return + */ + @Override + public List> chooseLabels(List> labelList) { + List> labels = new ArrayList<>(labelList); + Optional engineTypeLabelOption = + labels.stream() + .filter(label -> label instanceof EngineTypeLabel) + .map(label -> (EngineTypeLabel) label) + .findFirst(); + if (engineTypeLabelOption.isPresent()) { + EngineTypeLabel engineTypeLabel = engineTypeLabelOption.get(); + Optional maybeString = + Stream.of(multiUserEngine) + .filter(engineTypeLabel.getEngineType()::equalsIgnoreCase) + .findFirst(); + Optional userCreatorLabelOption = + labels.stream() + .filter(label -> label instanceof UserCreatorLabel) + .map(label -> (UserCreatorLabel) label) + .findFirst(); + if (maybeString.isPresent() && userCreatorLabelOption.isPresent()) { + String userAdmin = userMap.get(engineTypeLabel.getEngineType()); + UserCreatorLabel userCreatorLabel = userCreatorLabelOption.get(); + logger.info( + String.format( + "For multi user engine to reset userCreatorLabel user %s to Admin %s", + userCreatorLabel.getUser(), userAdmin)); + userCreatorLabel.setUser(userAdmin); + return labels; + } + } + return labelList; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/DefaultEngineNodeLocker.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/DefaultEngineNodeLocker.java new file mode 100644 index 0000000000..00adf1492b --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/DefaultEngineNodeLocker.java @@ -0,0 +1,73 @@ +/* + * 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.linkis.manager.am.locker; + +import org.apache.linkis.manager.common.entity.node.AMEngineNode; +import org.apache.linkis.manager.common.entity.node.EngineNode; +import org.apache.linkis.manager.common.protocol.RequestEngineLock; +import org.apache.linkis.manager.common.protocol.RequestEngineUnlock; +import org.apache.linkis.manager.common.protocol.RequestManagerUnlock; +import org.apache.linkis.manager.common.protocol.engine.EngineLockType; +import org.apache.linkis.manager.service.common.pointer.NodePointerBuilder; +import org.apache.linkis.rpc.message.annotation.Receiver; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class DefaultEngineNodeLocker implements EngineNodeLocker { + private static final Logger logger = LoggerFactory.getLogger(DefaultEngineNodeLocker.class); + + @Autowired private NodePointerBuilder nodeBuilder; + + @Override + public Optional lockEngine(EngineNode engineNode, long timeout) { + return nodeBuilder + .buildEngineNodePointer(engineNode) + .lockEngine(new RequestEngineLock(timeout, EngineLockType.Timed)); + } + + @Override + public void releaseLock(EngineNode engineNode, String lock) { + nodeBuilder.buildEngineNodePointer(engineNode).releaseLock(new RequestEngineUnlock(lock)); + } + + @Receiver + public void releaseLock(RequestManagerUnlock requestManagerUnlock) { + try { + logger.info( + String.format( + "client%s Start to unlock engine %s", + requestManagerUnlock.getClientInstance(), requestManagerUnlock.getEngineInstance())); + AMEngineNode engineNode = new AMEngineNode(); + engineNode.setServiceInstance(requestManagerUnlock.getEngineInstance()); + releaseLock(engineNode, requestManagerUnlock.getLock()); + logger.info( + String.format( + "client%s Finished to unlock engine %s", + requestManagerUnlock.getClientInstance(), requestManagerUnlock.getEngineInstance())); + } catch (Exception e) { + logger.error("release lock failed", e); + } + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/service/common/label/LabelFilter.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/EngineNodeLocker.java similarity index 73% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/service/common/label/LabelFilter.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/EngineNodeLocker.java index f65cc491aa..171714b333 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/service/common/label/LabelFilter.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/locker/EngineNodeLocker.java @@ -15,16 +15,15 @@ * limitations under the License. */ -package org.apache.linkis.manager.service.common.label +package org.apache.linkis.manager.am.locker; -import org.apache.linkis.manager.label.entity.Label +import org.apache.linkis.manager.common.entity.node.EngineNode; -import java.util +import java.util.Optional; -trait LabelFilter { +public interface EngineNodeLocker { - def choseEngineLabel(labelList: util.List[Label[_]]): util.List[Label[_]] - - def choseEMLabel(labelList: util.List[Label[_]]): util.List[Label[_]] + Optional lockEngine(EngineNode engineNode, long timeout); + void releaseLock(EngineNode engineNode, String lock); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEMNodeManager.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEMNodeManager.java new file mode 100644 index 0000000000..cf66e88e5d --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEMNodeManager.java @@ -0,0 +1,218 @@ +/* + * 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.linkis.manager.am.manager; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.common.entity.metrics.NodeMetrics; +import org.apache.linkis.manager.common.entity.node.*; +import org.apache.linkis.manager.common.entity.persistence.PersistenceNodeEntity; +import org.apache.linkis.manager.common.protocol.em.ECMOperateRequest; +import org.apache.linkis.manager.common.protocol.em.ECMOperateResponse; +import org.apache.linkis.manager.common.protocol.engine.EngineStopRequest; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnLaunchRequest; +import org.apache.linkis.manager.exception.NodeInstanceDuplicateException; +import org.apache.linkis.manager.persistence.NodeManagerPersistence; +import org.apache.linkis.manager.persistence.NodeMetricManagerPersistence; +import org.apache.linkis.manager.rm.ResourceInfo; +import org.apache.linkis.manager.rm.service.ResourceManager; +import org.apache.linkis.manager.service.common.metrics.MetricsConverter; +import org.apache.linkis.manager.service.common.pointer.NodePointerBuilder; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class DefaultEMNodeManager implements EMNodeManager { + private static final Logger logger = LoggerFactory.getLogger(DefaultEMNodeManager.class); + + @Autowired private NodeManagerPersistence nodeManagerPersistence; + + @Autowired private NodeMetricManagerPersistence nodeMetricManagerPersistence; + + @Autowired private MetricsConverter metricsConverter; + + @Autowired private NodePointerBuilder nodePointerBuilder; + + @Autowired private ResourceManager resourceManager; + + @Override + public void emRegister(EMNode emNode) { + nodeManagerPersistence.addNodeInstance(emNode); + // init metric + nodeMetricManagerPersistence.addOrupdateNodeMetrics( + metricsConverter.getInitMetric(emNode.getServiceInstance())); + } + + @Override + public void addEMNodeInstance(EMNode emNode) { + try { + nodeManagerPersistence.addNodeInstance(emNode); + } catch (NodeInstanceDuplicateException e) { + logger.warn("em instance had exists, {}.", emNode); + nodeManagerPersistence.updateEngineNode(emNode.getServiceInstance(), emNode); + } + } + + @Override + public void initEMNodeMetrics(EMNode emNode) { + nodeMetricManagerPersistence.addOrupdateNodeMetrics( + metricsConverter.getInitMetric(emNode.getServiceInstance())); + } + + @Override + public List listEngines(EMNode emNode) { + List result = new ArrayList<>(); + List nodes = nodeManagerPersistence.getEngineNodeByEM(emNode.getServiceInstance()); + Map metricses = new HashMap<>(); + for (NodeMetrics m : nodeMetricManagerPersistence.getNodeMetrics(nodes)) { + metricses.put(m.getServiceInstance().toString(), m); + } + for (EngineNode node : nodes) { + NodeMetrics metrics = metricses.get(node.getServiceInstance().toString()); + if (metrics != null) { + metricsConverter.fillMetricsToNode(node, metrics); + } + result.add(node); + } + return result; + } + + @Override + public List listUserEngines(EMNode emNode, String user) { + List result = new ArrayList<>(); + for (EngineNode node : listEngines(emNode)) { + if (node.getOwner().equals(user)) { + result.add(node); + } + } + return result; + } + + @Override + public List listUserNodes(String user) { + return nodeManagerPersistence.getNodes(user); + } + + /** + * Get detailed em information from the persistence TODO add label to node ? + * + * @param scoreServiceInstances + * @return + */ + @Override + public EMNode[] getEMNodes(ScoreServiceInstance[] scoreServiceInstances) { + if (null == scoreServiceInstances || scoreServiceInstances.length == 0) { + return null; + } + EMNode[] emNodes = + Arrays.stream(scoreServiceInstances) + .map( + scoreServiceInstance -> { + AMEMNode emNode = new AMEMNode(); + emNode.setScore(scoreServiceInstance.getScore()); + emNode.setServiceInstance(scoreServiceInstance.getServiceInstance()); + return emNode; + }) + .toArray(EMNode[]::new); + + // 1. add nodeMetrics 2 add RM info + ResourceInfo resourceInfo = + resourceManager.getResourceInfo( + Arrays.stream(scoreServiceInstances) + .map(ScoreServiceInstance::getServiceInstance) + .toArray(ServiceInstance[]::new)); + List nodeMetrics = + nodeMetricManagerPersistence.getNodeMetrics(Arrays.asList(emNodes)); + + for (EMNode emNode : emNodes) { + Optional optionMetrics = + nodeMetrics.stream() + .filter(metrics -> metrics.getServiceInstance().equals(emNode.getServiceInstance())) + .findFirst(); + Optional optionRMNode = + resourceInfo.getResourceInfo().stream() + .filter(rmNode -> rmNode.getServiceInstance().equals(emNode.getServiceInstance())) + .findFirst(); + + optionMetrics.ifPresent(metrics -> metricsConverter.fillMetricsToNode(emNode, metrics)); + optionRMNode.ifPresent(rmNode -> emNode.setNodeResource(rmNode.getNodeResource())); + } + return emNodes; + } + + @Override + public EMNode getEM(ServiceInstance serviceInstance) { + Node node = nodeManagerPersistence.getNode(serviceInstance); + if (null == node) { + logger.info("This em of " + serviceInstance + " not exists in db"); + return null; + } + AMEMNode emNode = new AMEMNode(); + emNode.setOwner(node.getOwner()); + emNode.setServiceInstance(node.getServiceInstance()); + if (node instanceof PersistenceNodeEntity) { + emNode.setStartTime(((PersistenceNodeEntity) node).getStartTime()); + } + emNode.setMark(emNode.getMark()); + metricsConverter.fillMetricsToNode(emNode, nodeMetricManagerPersistence.getNodeMetrics(emNode)); + return emNode; + } + + @Override + public void stopEM(EMNode emNode) { + nodePointerBuilder.buildEMNodePointer(emNode).stopNode(); + } + + @Override + public void deleteEM(EMNode emNode) { + nodeManagerPersistence.removeNodeInstance(emNode); + logger.info("Finished to clear emNode instance(" + emNode.getServiceInstance() + ") info "); + nodeMetricManagerPersistence.deleteNodeMetrics(emNode); + logger.info("Finished to clear emNode(" + emNode.getServiceInstance() + ") metrics info"); + } + + @Override + public void pauseEM(ServiceInstance serviceInstance) {} + + /** + * 1. request engineManager to launch engine + * + * @param engineBuildRequest + * @param emNode + * @return + */ + @Override + public EngineNode createEngine(EngineConnLaunchRequest engineConnLaunchRequest, EMNode emNode) { + return nodePointerBuilder.buildEMNodePointer(emNode).createEngine(engineConnLaunchRequest); + } + + @Override + public void stopEngine(EngineStopRequest engineStopRequest, EMNode emNode) { + nodePointerBuilder.buildEMNodePointer(emNode).stopEngine(engineStopRequest); + } + + @Override + public ECMOperateResponse executeOperation(EMNode ecmNode, ECMOperateRequest request) { + return nodePointerBuilder.buildEMNodePointer(ecmNode).executeOperation(request); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEngineNodeManager.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEngineNodeManager.java new file mode 100644 index 0000000000..e6049448e3 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/DefaultEngineNodeManager.java @@ -0,0 +1,346 @@ +/* + * 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.linkis.manager.am.manager; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.common.exception.LinkisRetryException; +import org.apache.linkis.manager.am.conf.AMConfiguration; +import org.apache.linkis.manager.am.exception.AMErrorCode; +import org.apache.linkis.manager.am.exception.AMErrorException; +import org.apache.linkis.manager.am.locker.EngineNodeLocker; +import org.apache.linkis.manager.am.utils.DefaultRetryHandler; +import org.apache.linkis.manager.am.utils.RetryHandler; +import org.apache.linkis.manager.common.constant.AMConstant; +import org.apache.linkis.manager.common.entity.enumeration.NodeStatus; +import org.apache.linkis.manager.common.entity.metrics.NodeMetrics; +import org.apache.linkis.manager.common.entity.node.*; +import org.apache.linkis.manager.common.entity.persistence.PersistenceLabel; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateRequest; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateResponse; +import org.apache.linkis.manager.common.protocol.node.NodeHeartbeatMsg; +import org.apache.linkis.manager.label.builder.factory.LabelBuilderFactory; +import org.apache.linkis.manager.label.builder.factory.LabelBuilderFactoryContext; +import org.apache.linkis.manager.label.entity.engine.EngineInstanceLabel; +import org.apache.linkis.manager.persistence.LabelManagerPersistence; +import org.apache.linkis.manager.persistence.NodeManagerPersistence; +import org.apache.linkis.manager.persistence.NodeMetricManagerPersistence; +import org.apache.linkis.manager.rm.ResourceInfo; +import org.apache.linkis.manager.rm.service.ResourceManager; +import org.apache.linkis.manager.service.common.metrics.MetricsConverter; +import org.apache.linkis.manager.service.common.pointer.EngineNodePointer; +import org.apache.linkis.manager.service.common.pointer.NodePointerBuilder; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.lang.reflect.UndeclaredThrowableException; +import java.util.*; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Service +public class DefaultEngineNodeManager implements EngineNodeManager { + private static final Logger logger = LoggerFactory.getLogger(DefaultEngineNodeManager.class); + + @Autowired private EngineNodeLocker engineLocker; + + @Autowired private NodeManagerPersistence nodeManagerPersistence; + + @Autowired private NodeMetricManagerPersistence nodeMetricManagerPersistence; + + @Autowired private MetricsConverter metricsConverter; + + @Autowired private NodePointerBuilder nodePointerBuilder; + + @Autowired private ResourceManager resourceManager; + + @Autowired private LabelManagerPersistence labelManagerPersistence; + + private final LabelBuilderFactory labelBuilderFactory = + LabelBuilderFactoryContext.getLabelBuilderFactory(); + + @Override + public List listEngines(String user) { + List userNodes = nodeManagerPersistence.getNodes(user); + + List nodes = + userNodes.stream() + .map(Node::getServiceInstance) + .map(nodeManagerPersistence::getEngineNode) + .collect(Collectors.toList()); + + List nodeMetrics = nodeMetricManagerPersistence.getNodeMetrics(nodes); + Map metricses = + nodeMetrics.stream() + .collect(Collectors.toMap(m -> m.getServiceInstance().toString(), m -> m)); + + nodes.forEach( + node -> { + Optional nodeMetricsOptional = + Optional.ofNullable(metricses.get(node.getServiceInstance().toString())); + nodeMetricsOptional.ifPresent(m -> metricsConverter.fillMetricsToNode(node, m)); + }); + return nodes; + } + + @Override + public EngineNode getEngineNodeInfo(EngineNode engineNode) { + /** Change the EngineNode to correspond to real-time requests?(修改为实时请求对应的EngineNode) */ + EngineNodePointer engine = nodePointerBuilder.buildEngineNodePointer(engineNode); + NodeHeartbeatMsg heartMsg = engine.getNodeHeartbeatMsg(); + engineNode.setNodeHealthyInfo(heartMsg.getHealthyInfo()); + engineNode.setNodeOverLoadInfo(heartMsg.getOverLoadInfo()); + engineNode.setNodeStatus(heartMsg.getStatus()); + return engineNode; + } + + @Override + public EngineNode getEngineNodeInfoByDB(EngineNode engineNode) { + // 1. 从持久化器中获取EngineNode信息,需要获取Task信息和Status信息,方便后面使用 + engineNode = nodeManagerPersistence.getEngineNode(engineNode.getServiceInstance()); + metricsConverter.fillMetricsToNode( + engineNode, nodeMetricManagerPersistence.getNodeMetrics(engineNode)); + return engineNode; + } + + @Override + public void updateEngineStatus( + ServiceInstance serviceInstance, NodeStatus fromState, NodeStatus toState) {} + + @Override + public void updateEngine(EngineNode engineNode) { + nodeManagerPersistence.updateNodeInstance(engineNode); + } + + @Override + public EngineNode switchEngine(EngineNode engineNode) { + return null; + } + + @Override + public EngineNode reuseEngine(EngineNode engineNode) { + EngineNode node = getEngineNodeInfo(engineNode); + if (!NodeStatus.isAvailable(node.getNodeStatus())) { + return null; + } + if (!NodeStatus.isLocked(node.getNodeStatus())) { + Optional lockStr = + engineLocker.lockEngine(node, (long) AMConfiguration.ENGINE_LOCKER_MAX_TIME.getValue()); + if (!lockStr.isPresent()) { + throw new LinkisRetryException( + AMConstant.ENGINE_ERROR_CODE, + String.format( + "Failed to request lock from engine by reuse %s", node.getServiceInstance())); + } + node.setLock(lockStr.get()); + return node; + } else { + return null; + } + } + + /** + * TODO use Engine需要考虑流式引擎的场景,后续需要通过Label加额外的处理 + * + * @param engineNode + * @param timeout + * @return + */ + @Override + public EngineNode useEngine(EngineNode engineNode, long timeout) { + RetryHandler retryHandler = new DefaultRetryHandler(); + retryHandler.addRetryException(feign.RetryableException.class); + retryHandler.addRetryException(UndeclaredThrowableException.class); + + // wait until engine to be available + EngineNode node = retryHandler.retry(() -> getEngineNodeInfo(engineNode), "getEngineNodeInfo"); + long retryEndTime = System.currentTimeMillis() + 60 * 1000; + while (!NodeStatus.isAvailable(node.getNodeStatus()) + && System.currentTimeMillis() < retryEndTime) { + node = retryHandler.retry(() -> getEngineNodeInfo(engineNode), "getEngineNodeInfo"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException e) { + // ignore + } + } + + if (!NodeStatus.isAvailable(node.getNodeStatus())) { + return null; + } + if (!NodeStatus.isLocked(node.getNodeStatus())) { + Optional lockStr = engineLocker.lockEngine(node, timeout); + if (!lockStr.isPresent()) { + throw new LinkisRetryException( + AMConstant.ENGINE_ERROR_CODE, + String.format("Failed to request lock from engine %s", node.getServiceInstance())); + } + node.setLock(lockStr.get()); + return node; + } else { + return null; + } + } + + /** + * Get detailed engine information from the persistence //TODO 是否增加owner到node + * + * @param scoreServiceInstances + * @return + */ + @Override + public EngineNode[] getEngineNodes(ScoreServiceInstance[] scoreServiceInstances) { + if (scoreServiceInstances == null || scoreServiceInstances.length == 0) { + return null; + } + EngineNode[] engineNodes = + Arrays.stream(scoreServiceInstances) + .map( + scoreServiceInstance -> { + AMEngineNode engineNode = new AMEngineNode(); + engineNode.setScore(scoreServiceInstance.getScore()); + engineNode.setServiceInstance(scoreServiceInstance.getServiceInstance()); + return engineNode; + }) + .toArray(EngineNode[]::new); + // 1. add nodeMetrics 2 add RM info + ServiceInstance[] serviceInstances = + Arrays.stream(scoreServiceInstances) + .map(ScoreServiceInstance::getServiceInstance) + .toArray(ServiceInstance[]::new); + ResourceInfo resourceInfo = resourceManager.getResourceInfo(serviceInstances); + + List nodeMetrics = + nodeMetricManagerPersistence.getNodeMetrics( + Arrays.stream(engineNodes).collect(Collectors.toList())); + Arrays.stream(engineNodes) + .forEach( + engineNode -> { + Optional optionMetrics = + nodeMetrics.stream() + .filter( + nodeMetric -> + nodeMetric + .getServiceInstance() + .equals(engineNode.getServiceInstance())) + .findFirst(); + + Optional optionRMNode = + resourceInfo.getResourceInfo().stream() + .filter( + resourceNode -> + resourceNode + .getServiceInstance() + .equals(engineNode.getServiceInstance())) + .findFirst(); + + optionMetrics.ifPresent( + metrics -> metricsConverter.fillMetricsToNode(engineNode, metrics)); + optionRMNode.ifPresent( + rmNode -> engineNode.setNodeResource(rmNode.getNodeResource())); + }); + return engineNodes; + } + + /** + * add info to persistence + * + * @param engineNode + */ + @Override + public void addEngineNode(EngineNode engineNode) { + nodeManagerPersistence.addEngineNode(engineNode); + // init metric + nodeMetricManagerPersistence.addOrupdateNodeMetrics( + metricsConverter.getInitMetric(engineNode.getServiceInstance())); + } + + /** + * delete info to persistence + * + * @param engineNode + */ + @Override + public void deleteEngineNode(EngineNode engineNode) { + nodeManagerPersistence.deleteEngineNode(engineNode); + } + + @Override + public EngineNode getEngineNode(ServiceInstance serviceInstance) { + return nodeManagerPersistence.getEngineNode(serviceInstance); + } + + /** + * 1.serviceInstance中取出instance(实际是ticketId) 2.update serviceInstance 表,包括 + * instance替换,替换mark,owner,updator,creator的空值,更新updateTime 3.update engine_em关联表 4.update label + * ticket_id ==> instance + * + * @param serviceInstance + * @param engineNode + */ + @Override + public void updateEngineNode(ServiceInstance serviceInstance, EngineNode engineNode) { + nodeManagerPersistence.updateEngineNode(serviceInstance, engineNode); + nodeMetricManagerPersistence.deleteNodeMetrics(engineNode); + + EngineInstanceLabel engineLabel = labelBuilderFactory.createLabel(EngineInstanceLabel.class); + engineLabel.setInstance(engineNode.getServiceInstance().getInstance()); + engineLabel.setServiceName(engineNode.getServiceInstance().getApplicationName()); + + EngineInstanceLabel oldEngineLabel = labelBuilderFactory.createLabel(EngineInstanceLabel.class); + oldEngineLabel.setInstance(serviceInstance.getInstance()); + oldEngineLabel.setServiceName(engineNode.getServiceInstance().getApplicationName()); + PersistenceLabel oldPersistenceLabel = + labelBuilderFactory.convertLabel(oldEngineLabel, PersistenceLabel.class); + PersistenceLabel label = + labelManagerPersistence.getLabelByKeyValue( + oldPersistenceLabel.getLabelKey(), oldPersistenceLabel.getStringValue()); + + PersistenceLabel persistenceLabel = + labelBuilderFactory.convertLabel(engineLabel, PersistenceLabel.class); + persistenceLabel.setLabelValueSize(persistenceLabel.getValue().size()); + labelManagerPersistence.updateLabel(label.getId(), persistenceLabel); + } + + public EngineOperateResponse executeOperation( + EngineNode engineNode, EngineOperateRequest request) { + EngineNodePointer engine = nodePointerBuilder.buildEngineNodePointer(engineNode); + return engine.executeOperation(request); + } + + public EngineNode getEngineNodeInfo(ServiceInstance serviceInstance) { + EngineNode engineNode = getEngineNode(serviceInstance); + if (Objects.isNull(engineNode)) { + throw new AMErrorException( + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorCode(), + AMErrorCode.NOT_EXISTS_ENGINE_CONN.getErrorDesc()); + } + + if (engineNode.getNodeStatus() == null) { + NodeMetrics nodeMetric = nodeMetricManagerPersistence.getNodeMetrics(engineNode); + if (Objects.nonNull(nodeMetric) && Objects.nonNull(nodeMetric.getStatus())) { + engineNode.setNodeStatus(NodeStatus.values()[nodeMetric.getStatus()]); + } else { + engineNode.setNodeStatus(NodeStatus.Starting); + } + } + return engineNode; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EMNodeManager.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EMNodeManager.java new file mode 100644 index 0000000000..8cb8362ecc --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EMNodeManager.java @@ -0,0 +1,73 @@ +/* + * 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.linkis.manager.am.manager; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.common.entity.node.EMNode; +import org.apache.linkis.manager.common.entity.node.EngineNode; +import org.apache.linkis.manager.common.entity.node.ScoreServiceInstance; +import org.apache.linkis.manager.common.protocol.em.ECMOperateRequest; +import org.apache.linkis.manager.common.protocol.em.ECMOperateResponse; +import org.apache.linkis.manager.common.protocol.engine.EngineStopRequest; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnLaunchRequest; + +import java.util.List; + +public interface EMNodeManager { + + void emRegister(EMNode emNode); + + List listEngines(EMNode emNode); + + List listUserEngines(EMNode emNode, String user); + + List listUserNodes(String user); + + /** + * Get detailed em information from the persistence + * + * @param scoreServiceInstances + * @return + */ + EMNode[] getEMNodes(ScoreServiceInstance[] scoreServiceInstances); + + EMNode getEM(ServiceInstance serviceInstance); + + void stopEM(EMNode emNode); + + void deleteEM(EMNode emNode); + + void pauseEM(ServiceInstance serviceInstance); + + /** + * 1. request engineManager to launch engine 2. persist engine info + * + * @param engineConnLaunchRequest engine launch request + * @param emNode ecm node + * @return engine node + */ + EngineNode createEngine(EngineConnLaunchRequest engineConnLaunchRequest, EMNode emNode); + + void stopEngine(EngineStopRequest engineStopRequest, EMNode emNode); + + void addEMNodeInstance(EMNode emNode); + + void initEMNodeMetrics(EMNode emNode); + + ECMOperateResponse executeOperation(EMNode ecmNode, ECMOperateRequest request); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EngineNodeManager.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EngineNodeManager.java new file mode 100644 index 0000000000..252d97c0bf --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/manager/EngineNodeManager.java @@ -0,0 +1,67 @@ +/* + * 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.linkis.manager.am.manager; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.common.entity.enumeration.NodeStatus; +import org.apache.linkis.manager.common.entity.node.EngineNode; +import org.apache.linkis.manager.common.entity.node.ScoreServiceInstance; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateRequest; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateResponse; + +import java.util.List; + +public interface EngineNodeManager { + + List listEngines(String user); + + EngineNode getEngineNode(ServiceInstance serviceInstance); + + EngineNode getEngineNodeInfo(EngineNode engineNode); + + EngineNode getEngineNodeInfo(ServiceInstance serviceInstance); + + EngineNode getEngineNodeInfoByDB(EngineNode engineNode); + + /** + * Get detailed engine information from the persistence + * + * @param scoreServiceInstances + * @return + */ + EngineNode[] getEngineNodes(ScoreServiceInstance[] scoreServiceInstances); + + void updateEngineStatus( + ServiceInstance serviceInstance, NodeStatus fromState, NodeStatus toState); + + void addEngineNode(EngineNode engineNode); + + void updateEngineNode(ServiceInstance serviceInstance, EngineNode engineNode); + + void updateEngine(EngineNode engineNode); + + void deleteEngineNode(EngineNode engineNode); + + EngineNode switchEngine(EngineNode engineNode); + + EngineNode reuseEngine(EngineNode engineNode); + + EngineNode useEngine(EngineNode engineNode, long timeout); + + EngineOperateResponse executeOperation(EngineNode engineNode, EngineOperateRequest request); +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/AbstractNodePointer.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/AbstractNodePointer.java new file mode 100644 index 0000000000..80390d0883 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/AbstractNodePointer.java @@ -0,0 +1,98 @@ +/* + * 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.linkis.manager.am.pointer; + +import org.apache.linkis.common.exception.WarnException; +import org.apache.linkis.manager.common.entity.enumeration.NodeStatus; +import org.apache.linkis.manager.common.entity.node.Node; +import org.apache.linkis.manager.common.protocol.node.*; +import org.apache.linkis.manager.label.entity.Label; +import org.apache.linkis.manager.service.common.pointer.NodePointer; +import org.apache.linkis.rpc.Sender; + +public abstract class AbstractNodePointer implements NodePointer { + + protected Sender getSender() { + return Sender.getSender(getNode().getServiceInstance()); + } + + /** + * 向对应的Node发送请求获取节点状态 + * + * @return + */ + @Override + public NodeStatus getNodeStatus() { + Sender sender = getSender(); + try { + ResponseNodeStatus responseStatus = (ResponseNodeStatus) sender.ask(new RequestNodeStatus()); + return responseStatus.getNodeStatus(); + } catch (WarnException e) { + throw e; + } + } + + /** + * 向对应的Node发送请求获取节点心跳信息 + * + * @return + */ + @Override + public NodeHeartbeatMsg getNodeHeartbeatMsg() { + Sender sender = getSender(); + try { + NodeHeartbeatMsg heartbeatMsg = (NodeHeartbeatMsg) sender.ask(new NodeHeartbeatRequest()); + return heartbeatMsg; + } catch (WarnException e) { + throw e; + } + } + + /** + * 向对应的Node发送Kill 请求 + * + * @return + */ + @Override + public void stopNode() { + Sender sender = getSender(); + sender.send(new StopNodeRequest()); + } + + /** + * 向对应的Node Label 更新请求 + * + * @return + */ + @Override + public void updateLabels(Label[] labels) {} + + @Override + public void updateNodeHealthyRequest(NodeHealthyRequest nodeHealthyRequest) { + getSender().send(nodeHealthyRequest); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Node) { + Node nodeB = (Node) obj; + return getNode().getServiceInstance().equals(nodeB.getServiceInstance()); + } + return false; + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEMNodPointer.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEMNodPointer.java new file mode 100644 index 0000000000..73d3c47705 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEMNodPointer.java @@ -0,0 +1,110 @@ +/* + * 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.linkis.manager.am.pointer; + +import org.apache.linkis.manager.am.exception.AMErrorException; +import org.apache.linkis.manager.common.constant.AMConstant; +import org.apache.linkis.manager.common.entity.node.EngineNode; +import org.apache.linkis.manager.common.entity.node.Node; +import org.apache.linkis.manager.common.protocol.em.ECMOperateRequest; +import org.apache.linkis.manager.common.protocol.em.ECMOperateResponse; +import org.apache.linkis.manager.common.protocol.engine.EngineStopRequest; +import org.apache.linkis.manager.common.protocol.engine.EngineStopResponse; +import org.apache.linkis.manager.engineplugin.common.launch.entity.EngineConnLaunchRequest; +import org.apache.linkis.manager.service.common.pointer.EMNodPointer; +import org.apache.linkis.server.BDPJettyServerHelper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DefaultEMNodPointer extends AbstractNodePointer implements EMNodPointer { + private static final Logger logger = LoggerFactory.getLogger(DefaultEMNodPointer.class); + + private Node node; + + public DefaultEMNodPointer(Node node) { + this.node = node; + } + + /** + * 与该远程指针关联的node信息 + * + * @return + */ + @Override + public Node getNode() { + return node; + } + + @Override + public EngineNode createEngine(EngineConnLaunchRequest engineConnLaunchRequest) { + logger.info("Start to createEngine ask em " + getNode().getServiceInstance()); + Object result = getSender().ask(engineConnLaunchRequest); + if (result instanceof EngineNode) { + EngineNode engineNode = (EngineNode) result; + logger.info( + "Succeed to createEngine ask em " + + getNode().getServiceInstance() + + ", engineNode " + + engineNode); + return engineNode; + } else { + throw new AMErrorException( + AMConstant.ENGINE_ERROR_CODE, + "Failed to createEngine ask em " + getNode().getServiceInstance()); + } + } + + @Override + public void stopEngine(EngineStopRequest engineStopRequest) { + Object result = getSender().ask(engineStopRequest); + if (result instanceof EngineStopResponse) { + EngineStopResponse engineStopResponse = (EngineStopResponse) result; + if (!engineStopResponse.getStopStatus()) { + logger.info( + "Kill engine : " + + engineStopRequest.getServiceInstance().toString() + + " failed, because " + + engineStopResponse.getMsg() + + " . Will ask engine to suicide."); + } else { + logger.info( + "Succeed to kill engine " + engineStopRequest.getServiceInstance().toString() + "."); + } + } else { + logger.warn( + "Ask em : " + + getNode().getServiceInstance().toString() + + " to kill engine : " + + engineStopRequest.getServiceInstance().toString() + + " failed, response is : " + + BDPJettyServerHelper.gson().toJson(result) + + "."); + } + } + + @Override + public ECMOperateResponse executeOperation(ECMOperateRequest ecmOperateRequest) { + Object result = getSender().ask(ecmOperateRequest); + if (result instanceof ECMOperateResponse) { + return (ECMOperateResponse) result; + } else { + throw new AMErrorException(AMConstant.ENGINE_ERROR_CODE, "Failed to execute ECM operation."); + } + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEngineNodPointer.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEngineNodPointer.java new file mode 100644 index 0000000000..21f86f83d1 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultEngineNodPointer.java @@ -0,0 +1,82 @@ +/* + * 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.linkis.manager.am.pointer; + +import org.apache.linkis.manager.am.exception.AMErrorException; +import org.apache.linkis.manager.common.entity.node.Node; +import org.apache.linkis.manager.common.protocol.RequestEngineLock; +import org.apache.linkis.manager.common.protocol.RequestEngineUnlock; +import org.apache.linkis.manager.common.protocol.ResponseEngineLock; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateRequest; +import org.apache.linkis.manager.common.protocol.engine.EngineOperateResponse; +import org.apache.linkis.manager.service.common.pointer.EngineNodePointer; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DefaultEngineNodPointer extends AbstractNodePointer implements EngineNodePointer { + private static final Logger logger = LoggerFactory.getLogger(DefaultEngineNodPointer.class); + + private Node node; + + public DefaultEngineNodPointer(Node node) { + this.node = node; + } + + @Override + public Node getNode() { + return node; + } + + @Override + public Optional lockEngine(RequestEngineLock requestEngineLock) { + Object result = getSender().ask(requestEngineLock); + if (result instanceof ResponseEngineLock) { + ResponseEngineLock responseEngineLock = (ResponseEngineLock) result; + if (responseEngineLock.getLockStatus()) { + return Optional.of(responseEngineLock.getLock()); + } else { + logger.info( + "Failed to get locker," + + node.getServiceInstance() + + ": " + + responseEngineLock.getMsg()); + return Optional.empty(); + } + } else { + return Optional.empty(); + } + } + + @Override + public void releaseLock(RequestEngineUnlock requestEngineUnlock) { + getSender().send(requestEngineUnlock); + } + + @Override + public EngineOperateResponse executeOperation(EngineOperateRequest engineOperateRequest) { + Object result = getSender().ask(engineOperateRequest); + if (result instanceof EngineOperateResponse) { + return (EngineOperateResponse) result; + } else { + throw new AMErrorException(-1, "Illegal response of operation."); + } + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultNodePointerBuilder.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultNodePointerBuilder.java new file mode 100644 index 0000000000..03e0bc8087 --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/pointer/DefaultNodePointerBuilder.java @@ -0,0 +1,39 @@ +/* + * 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.linkis.manager.am.pointer; + +import org.apache.linkis.manager.common.entity.node.EMNode; +import org.apache.linkis.manager.common.entity.node.EngineNode; +import org.apache.linkis.manager.service.common.pointer.EMNodPointer; +import org.apache.linkis.manager.service.common.pointer.EngineNodePointer; +import org.apache.linkis.manager.service.common.pointer.NodePointerBuilder; + +import org.springframework.stereotype.Component; + +@Component +public class DefaultNodePointerBuilder implements NodePointerBuilder { + @Override + public EMNodPointer buildEMNodePointer(EMNode node) { + return new DefaultEMNodPointer(node); + } + + @Override + public EngineNodePointer buildEngineNodePointer(EngineNode node) { + return new DefaultEngineNodPointer(node); + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/AssignNodeRuleExecutor.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/AssignNodeRuleExecutor.java new file mode 100644 index 0000000000..f9a3acce4f --- /dev/null +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/AssignNodeRuleExecutor.java @@ -0,0 +1,42 @@ +/* + * 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.linkis.manager.am.recycle; + +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.common.entity.recycle.AssignNodeRule; +import org.apache.linkis.manager.common.entity.recycle.RecyclingRule; + +import org.springframework.stereotype.Component; + +@Component +public class AssignNodeRuleExecutor implements RecyclingRuleExecutor { + @Override + public boolean ifAccept(RecyclingRule recyclingRule) { + return recyclingRule instanceof AssignNodeRule; + } + + @Override + public ServiceInstance[] executeRule(RecyclingRule recyclingRule) { + if (recyclingRule instanceof AssignNodeRule) { + AssignNodeRule assignNodeRule = (AssignNodeRule) recyclingRule; + return new ServiceInstance[] {assignNodeRule.serviceInstance()}; + } else { + return null; + } + } +} diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.scala b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.java similarity index 77% rename from linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.scala rename to linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.java index 8a4db6fb03..ab53aa8281 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.scala +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/recycle/RecyclingRuleExecutor.java @@ -15,15 +15,14 @@ * limitations under the License. */ -package org.apache.linkis.manager.am.recycle +package org.apache.linkis.manager.am.recycle; -import org.apache.linkis.common.ServiceInstance -import org.apache.linkis.manager.common.entity.recycle.RecyclingRule +import org.apache.linkis.common.ServiceInstance; +import org.apache.linkis.manager.common.entity.recycle.RecyclingRule; -trait RecyclingRuleExecutor { +public interface RecyclingRuleExecutor { - def ifAccept(recyclingRule: RecyclingRule): Boolean - - def executeRule(recyclingRule: RecyclingRule): Array[ServiceInstance] + boolean ifAccept(RecyclingRule recyclingRule); + ServiceInstance[] executeRule(RecyclingRule recyclingRule); } diff --git a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/restful/EMRestfulApi.java b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/restful/EMRestfulApi.java index 05cda79c57..f35eb48b7e 100644 --- a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/restful/EMRestfulApi.java +++ b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/java/org/apache/linkis/manager/am/restful/EMRestfulApi.java @@ -35,9 +35,8 @@ import org.apache.linkis.manager.common.entity.node.EMNode; import org.apache.linkis.manager.common.entity.node.EngineNode; import org.apache.linkis.manager.common.entity.persistence.ECResourceInfoRecord; -import org.apache.linkis.manager.common.protocol.OperateRequest$; +import org.apache.linkis.manager.common.protocol.OperateRequest; import org.apache.linkis.manager.common.protocol.em.ECMOperateRequest; -import org.apache.linkis.manager.common.protocol.em.ECMOperateRequest$; import org.apache.linkis.manager.common.protocol.em.ECMOperateResponse; import org.apache.linkis.manager.label.builder.factory.LabelBuilderFactory; import org.apache.linkis.manager.label.builder.factory.LabelBuilderFactoryContext; @@ -99,7 +98,7 @@ public class EMRestfulApi { private Logger logger = LoggerFactory.getLogger(EMRestfulApi.class); - private String[] adminOperations = AMConfiguration.ECM_ADMIN_OPERATIONS().getValue().split(","); + private String[] adminOperations = AMConfiguration.ECM_ADMIN_OPERATIONS.getValue().split(","); private void checkAdmin(String userName) throws AMErrorException { if (Configuration.isNotAdmin(userName)) { @@ -149,7 +148,7 @@ public Message listAllEMs( stream = stream.filter( em -> { - List