From 15ce8f900b9a162a6606cd15db1a7b42064ac5c5 Mon Sep 17 00:00:00 2001 From: peacewong Date: Thu, 6 Jun 2024 16:25:04 +0800 Subject: [PATCH 01/21] Linkis Clent Feature optimization, adding FSClient and enriching LinkisManagerClient --- .../linkis/cli/application/CtxBuilder.java | 5 ++ .../application/LinkisClientApplication.java | 2 +- .../command/template/option/BaseOption.java | 2 +- .../command/template/option/Flag.java | 9 +- .../client/once/LinkisManagerClient.scala | 12 ++- .../once/action/ListEngineConnAction.scala | 48 +++++++++++ .../once/result/GetEngineConnResult.scala | 38 +++++++++ .../once/result/ListEngineConnResult.scala | 35 ++++++++ .../linkis/ujes/client/LinkisFSClient.scala | 46 +++++++++++ .../linkis/ujes/client/UJESClient.scala | 57 +++++++++++-- .../linkis/ujes/client/UJESClientImpl.scala | 2 +- .../client/request/CreateNewDirAction.scala | 61 ++++++++++++++ .../client/request/IsPathExistAction.scala | 56 +++++++++++++ .../ujes/client/request/ResultSetAction.scala | 8 ++ .../client/request/UploadFileAction.scala | 82 +++++++++++++++++++ .../client/response/CreateNewDirResult.scala | 25 ++++++ .../client/response/IsPathExistResult.scala | 29 +++++++ .../client/response/ResultSetResult.scala | 28 +++++++ .../client/response/UploadFileResult.scala | 25 ++++++ .../ujes/client/utils/UJESClientUtils.scala | 36 ++++++++ 20 files changed, 585 insertions(+), 21 deletions(-) create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/action/ListEngineConnAction.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/ListEngineConnResult.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/LinkisFSClient.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/CreateNewDirAction.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/IsPathExistAction.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/UploadFileAction.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/CreateNewDirResult.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/IsPathExistResult.scala create mode 100644 linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/UploadFileResult.scala diff --git a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/CtxBuilder.java b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/CtxBuilder.java index 07df8b79ad..cfa57d4e26 100644 --- a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/CtxBuilder.java +++ b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/CtxBuilder.java @@ -73,11 +73,16 @@ public static CliCtx buildCtx(String[] args) throws LinkisClientRuntimeException ParseResult result = parser.parse(args); ParsedTplValidator parsedTplValidator = new ParsedTplValidator(); + parsedTplValidator.doValidation(result.getParsedTemplate()); Params params = result.getParams(); logger.debug("==========params============\n" + CliUtils.GSON.toJson(params)); + /* + VarAccess for sys_prop, sys_env + */ + Map propertiesMap = new HashMap<>(); LoggerManager.getInformationLogger() diff --git a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/LinkisClientApplication.java b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/LinkisClientApplication.java index 1fb21043a1..24ee3c8dcc 100644 --- a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/LinkisClientApplication.java +++ b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/LinkisClientApplication.java @@ -69,7 +69,7 @@ public static void main(String[] args) { CmdTemplate template = CmdTemplateFactory.getTemplateOri(e.getCmdType()); if (template != null) { HelpInfoModel model = new HelpInfoModel(); - model.buildModel(ctx.getTemplate()); + model.buildModel(template); new HelpPresenter().present(model); } LoggerManager.getInformationLogger().error("Failed to build CliCtx", e); diff --git a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/BaseOption.java b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/BaseOption.java index e497401bef..eee29c8e94 100644 --- a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/BaseOption.java +++ b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/BaseOption.java @@ -93,7 +93,7 @@ public void setValueWithStr(String value) throws IllegalArgumentException { } public T getValue() { - return this.value; + return this.value == null ? this.defaultValue : this.value; } public void setValue(T value) { diff --git a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/Flag.java b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/Flag.java index ee66a64463..47af30b0d0 100644 --- a/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/Flag.java +++ b/linkis-computation-governance/linkis-client/linkis-cli/src/main/java/org/apache/linkis/cli/application/interactor/command/template/option/Flag.java @@ -43,14 +43,9 @@ public Flag( @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("\t") - .append(StringUtils.join(paramNames, "|")) - .append(" <") - .append(this.getDefaultValue().getClass().getSimpleName()) - .append(">") - .append(System.lineSeparator()); + sb.append("\t").append(StringUtils.join(paramNames, "|")).append(System.lineSeparator()); - sb.append("\t\t").append(this.getDefaultValue()).append(System.lineSeparator()); + sb.append("\t\t").append(this.getDescription()).append(System.lineSeparator()); sb.append("\t\tdefault by: ").append(this.getDefaultValue()).append(System.lineSeparator()); diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/LinkisManagerClient.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/LinkisManagerClient.scala index 45f3f49bed..bc1bb75f55 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/LinkisManagerClient.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/LinkisManagerClient.scala @@ -24,7 +24,8 @@ import org.apache.linkis.computation.client.once.action.{ EngineConnOperateAction, GetEngineConnAction, KillEngineConnAction, - LinkisManagerAction + LinkisManagerAction, + ListEngineConnAction } import org.apache.linkis.computation.client.once.result.{ AskEngineConnResult, @@ -32,7 +33,8 @@ import org.apache.linkis.computation.client.once.result.{ EngineConnOperateResult, GetEngineConnResult, KillEngineConnResult, - LinkisManagerResult + LinkisManagerResult, + ListEngineConnResult } import org.apache.linkis.httpclient.dws.DWSHttpClient import org.apache.linkis.httpclient.request.Action @@ -50,6 +52,8 @@ trait LinkisManagerClient extends Closeable { def killEngineConn(killEngineConnAction: KillEngineConnAction): KillEngineConnResult + def listEngineConn(listEngineConnAction: ListEngineConnAction): ListEngineConnResult + def executeEngineConnOperation( engineConnOperateAction: EngineConnOperateAction ): EngineConnOperateResult @@ -104,4 +108,8 @@ class LinkisManagerClientImpl(ujesClient: UJESClient) extends LinkisManagerClien override def askEngineConn(askEngineConnAction: AskEngineConnAction): AskEngineConnResult = execute(askEngineConnAction) + override def listEngineConn(listEngineConnAction: ListEngineConnAction): ListEngineConnResult = { + execute(listEngineConnAction) + } + } diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/action/ListEngineConnAction.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/action/ListEngineConnAction.scala new file mode 100644 index 0000000000..c76a5e78e3 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/action/ListEngineConnAction.scala @@ -0,0 +1,48 @@ +/* + * 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.computation.client.once.action + +import org.apache.linkis.httpclient.request.GetAction +import org.apache.linkis.ujes.client.exception.UJESClientBuilderException + +class ListEngineConnAction extends GetAction with LinkisManagerAction { + override def suffixURLs: Array[String] = Array("linkisManager", "listUserEngines") +} + +object ListEngineConnAction { + def newBuilder(): Builder = new Builder + + class Builder private[ListEngineConnAction] () { + + private var user: String = _ + + def setUser(user: String): Builder = { + this.user = user + this + } + + def build(): ListEngineConnAction = { + if (user == null) throw new UJESClientBuilderException("user is needed!") + val listEngineConnAction = new ListEngineConnAction + listEngineConnAction.setUser(user) + listEngineConnAction + } + + } + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/GetEngineConnResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/GetEngineConnResult.scala index e964cd714c..b20923de89 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/GetEngineConnResult.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/GetEngineConnResult.scala @@ -17,6 +17,7 @@ package org.apache.linkis.computation.client.once.result +import org.apache.linkis.common.ServiceInstance import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult import java.util @@ -32,4 +33,41 @@ class GetEngineConnResult extends LinkisManagerResult { def getNodeInfo: util.Map[String, Any] = engineConnNode + protected def getAs[T](map: util.Map[String, Any], key: String): T = + map.get(key).asInstanceOf[T] + + def getTicketId(): String = getAs(engineConnNode, "ticketId") + + def getServiceInstance(): ServiceInstance = + engineConnNode.get("serviceInstance") match { + case serviceInstance: util.Map[String, Any] => + ServiceInstance( + getAs(serviceInstance, "applicationName"), + getAs(serviceInstance, "instance") + ) + case _ => null + } + + def getNodeStatus(): String = getAs(engineConnNode, "nodeStatus") + + def getECMServiceInstance(): ServiceInstance = + engineConnNode.get("ecmServiceInstance") match { + case serviceInstance: util.Map[String, Any] => + ServiceInstance( + getAs(serviceInstance, "applicationName"), + getAs(serviceInstance, "instance") + ) + case _ => null + } + + def getManagerServiceInstance(): ServiceInstance = + engineConnNode.get("managerServiceInstance") match { + case serviceInstance: util.Map[String, Any] => + ServiceInstance( + getAs(serviceInstance, "applicationName"), + getAs(serviceInstance, "instance") + ) + case _ => null + } + } diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/ListEngineConnResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/ListEngineConnResult.scala new file mode 100644 index 0000000000..c31ccf481f --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/computation/client/once/result/ListEngineConnResult.scala @@ -0,0 +1,35 @@ +/* + * 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.computation.client.once.result + +import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult + +import java.util + +@DWSHttpMessageResult("/api/rest_j/v\\d+/linkisManager/listUserEngines") +class ListEngineConnResult extends LinkisManagerResult { + + private var engines: util.List[util.Map[String, AnyRef]] = _ + + def setEngines(engines: util.List[util.Map[String, AnyRef]]): Unit = { + this.engines = engines + } + + def getEngines: util.List[util.Map[String, AnyRef]] = engines + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/LinkisFSClient.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/LinkisFSClient.scala new file mode 100644 index 0000000000..3e7f675592 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/LinkisFSClient.scala @@ -0,0 +1,46 @@ +/* + * 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.ujes.client + +import org.apache.linkis.ujes.client.request.{ + CreateNewDirAction, + IsPathExistAction, + UploadFileAction +} +import org.apache.linkis.ujes.client.response.{ + CreateNewDirResult, + IsPathExistResult, + UploadFileResult +} + +class LinkisFSClient(client: UJESClient) { + + def isPathExist(isPathExistAction: IsPathExistAction): Boolean = { + val result = client.executeUJESJob(isPathExistAction).asInstanceOf[IsPathExistResult] + result.isExist + } + + def createNewDir(makeDirAction: CreateNewDirAction): CreateNewDirResult = { + client.executeUJESJob(makeDirAction).asInstanceOf[CreateNewDirResult] + } + + def upload(uploadFileAction: UploadFileAction): UploadFileResult = { + client.executeUJESJob(uploadFileAction).asInstanceOf[UploadFileResult] + } + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClient.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClient.scala index 6431c47ebf..6657b7e4db 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClient.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClient.scala @@ -17,6 +17,7 @@ package org.apache.linkis.ujes.client +import org.apache.linkis.common.utils.{Logging, Utils} import org.apache.linkis.httpclient.authentication.AuthenticationStrategy import org.apache.linkis.httpclient.dws.authentication.StaticAuthenticationStrategy import org.apache.linkis.httpclient.dws.config.{DWSClientConfig, DWSClientConfigBuilder} @@ -24,11 +25,13 @@ import org.apache.linkis.httpclient.response.Result import org.apache.linkis.ujes.client.request._ import org.apache.linkis.ujes.client.request.JobExecIdAction.JobServiceType import org.apache.linkis.ujes.client.response._ +import org.apache.linkis.ujes.client.utils.UJESClientUtils import java.io.Closeable +import java.util import java.util.concurrent.TimeUnit -abstract class UJESClient extends Closeable { +abstract class UJESClient extends Closeable with Logging { def execute(jobExecuteAction: JobExecuteAction): JobExecuteResult = executeUJESJob( jobExecuteAction @@ -37,7 +40,7 @@ abstract class UJESClient extends Closeable { def submit(jobSubmitAction: JobSubmitAction): JobSubmitResult = executeUJESJob(jobSubmitAction).asInstanceOf[JobSubmitResult] - protected[client] def executeUJESJob(ujesJobAction: UJESJobAction): Result + def executeUJESJob(ujesJobAction: UJESJobAction): Result private def executeJobExecIdAction[T]( jobExecuteResult: JobExecuteResult, @@ -52,12 +55,34 @@ abstract class UJESClient extends Closeable { executeUJESJob(jobExecIdAction).asInstanceOf[T] } + /** + * only get the status of the cache Task status should be based on getJobInfo + * @param jobExecuteResult + * @return + */ def status(jobExecuteResult: JobExecuteResult): JobStatusResult = executeJobExecIdAction(jobExecuteResult, JobServiceType.JobStatus) + /** + * IF exception return null progress result + * @param jobExecuteResult + * @return + */ def progress(jobExecuteResult: JobExecuteResult): JobProgressResult = - executeJobExecIdAction(jobExecuteResult, JobServiceType.JobProgress) - + Utils.tryCatch(executeJobExecIdAction(jobExecuteResult, JobServiceType.JobProgress)) { t => + logger.warn("Failed to get progress, return empty progress.", t) + val result = new JobProgressResult + result.setProgress(0) + result + } + + /** + * If exception return null log + * @param jobExecuteResult + * @param fromLine + * @param size + * @return + */ def log(jobExecuteResult: JobExecuteResult, fromLine: Int, size: Int): JobLogResult = { val jobLogAction = JobLogAction .builder() @@ -66,13 +91,19 @@ abstract class UJESClient extends Closeable { .setFromLine(fromLine) .setSize(size) .build() - executeUJESJob(jobLogAction).asInstanceOf[JobLogResult] - } - def list(jobListAction: JobListAction): JobListResult = { - executeUJESJob(jobListAction).asInstanceOf[JobListResult] + Utils.tryCatch(executeUJESJob(jobLogAction).asInstanceOf[JobLogResult]) { t => + logger.warn("Failed to get Log, return empty log.", t) + null + } } + /** + * If exception return null log + * @param jobExecuteResult + * @param jobLogResult + * @return + */ def log(jobExecuteResult: JobExecuteResult, jobLogResult: JobLogResult): JobLogResult = { val jobLogAction = JobLogAction .builder() @@ -80,13 +111,21 @@ abstract class UJESClient extends Closeable { .setUser(jobExecuteResult.getUser) .setFromLine(jobLogResult.getFromLine) .build() - executeUJESJob(jobLogAction).asInstanceOf[JobLogResult] + + Utils.tryCatch(executeUJESJob(jobLogAction).asInstanceOf[JobLogResult]) { t => + logger.warn("Failed to get Log, return empty log.", t) + null + } } def openLog(openLogAction: OpenLogAction): OpenLogResult = { executeUJESJob(openLogAction).asInstanceOf[OpenLogResult] } + def list(jobListAction: JobListAction): JobListResult = { + executeUJESJob(jobListAction).asInstanceOf[JobListResult] + } + def kill(jobExecuteResult: JobExecuteResult): JobKillResult = executeJobExecIdAction(jobExecuteResult, JobServiceType.JobKill) diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClientImpl.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClientImpl.scala index b173f53d55..0feabaafda 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClientImpl.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/UJESClientImpl.scala @@ -26,7 +26,7 @@ import org.apache.linkis.ujes.client.request.UJESJobAction class UJESClientImpl(clientConfig: DWSClientConfig) extends UJESClient { private val dwsHttpClient = new DWSHttpClient(clientConfig, "Linkis-Job-Execution-Thread") - override protected[client] def executeUJESJob(ujesJobAction: UJESJobAction): Result = + override def executeUJESJob(ujesJobAction: UJESJobAction): Result = ujesJobAction match { case action: Action => dwsHttpClient.execute(action) } diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/CreateNewDirAction.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/CreateNewDirAction.scala new file mode 100644 index 0000000000..561bfc07d1 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/CreateNewDirAction.scala @@ -0,0 +1,61 @@ +/* + * 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.ujes.client.request + +import org.apache.linkis.httpclient.dws.DWSHttpClient +import org.apache.linkis.httpclient.request.POSTAction +import org.apache.linkis.ujes.client.exception.UJESClientBuilderException + +class CreateNewDirAction extends POSTAction with UJESJobAction { + + override def suffixURLs: Array[String] = Array("filesystem", "createNewDir") + + override def getRequestPayload: String = + DWSHttpClient.jacksonJson.writeValueAsString(getRequestPayloads) + +} + +object CreateNewDirAction { + def builder(): Builder = new Builder + + class Builder private[CreateNewDirAction] () { + private var user: String = _ + private var path: String = _ + + def setUser(user: String): Builder = { + this.user = user + this + } + + def setPath(path: String): Builder = { + this.path = path + this + } + + def build(): CreateNewDirAction = { + val makeDirAction = new CreateNewDirAction + if (user == null) throw new UJESClientBuilderException("user is needed!") + if (path == null) throw new UJESClientBuilderException("path is needed!") + makeDirAction.setUser(user) + makeDirAction.addRequestPayload("path", path) + makeDirAction + } + + } + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/IsPathExistAction.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/IsPathExistAction.scala new file mode 100644 index 0000000000..e9e74edd16 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/IsPathExistAction.scala @@ -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.ujes.client.request + +import org.apache.linkis.httpclient.request.GetAction +import org.apache.linkis.ujes.client.exception.UJESClientBuilderException + +class IsPathExistAction extends GetAction with UJESJobAction { + + override def suffixURLs: Array[String] = Array("filesystem", "isExist") +} + +object IsPathExistAction { + def builder(): Builder = new Builder + + class Builder private[IsPathExistAction] () { + private var user: String = _ + private var path: String = _ + + def setUser(user: String): Builder = { + this.user = user + this + } + + def setPath(path: String): Builder = { + this.path = path + this + } + + def build(): IsPathExistAction = { + val isPathExistAction = new IsPathExistAction + if (user == null) throw new UJESClientBuilderException("user is needed!") + if (path == null) throw new UJESClientBuilderException("path is needed!") + isPathExistAction.setUser(user) + isPathExistAction.setParameter("path", path) + isPathExistAction + } + + } + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/ResultSetAction.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/ResultSetAction.scala index 9eb748691e..45f0e8a89f 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/ResultSetAction.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/ResultSetAction.scala @@ -38,6 +38,8 @@ object ResultSetAction { // default value is :org.apache.linkis.storage.domain.Dolphin.LINKIS_NULL private var nullValue: String = "LINKIS_NULL" + private var enableLimit: Boolean = false + def setUser(user: String): Builder = { this.user = user this @@ -68,6 +70,11 @@ object ResultSetAction { this } + def setEnableLimit(enableLimit: Boolean): Builder = { + this.enableLimit = enableLimit + this + } + def build(): ResultSetAction = { if (user == null) throw new UJESClientBuilderException("user is needed!") if (path == null) throw new UJESClientBuilderException("path is needed!") @@ -76,6 +83,7 @@ object ResultSetAction { if (page > 0) resultSetAction.setParameter("page", page) if (pageSize > 0) resultSetAction.setParameter("pageSize", pageSize) resultSetAction.setParameter("charset", charset) + resultSetAction.setParameter("enableLimit", enableLimit) resultSetAction.setParameter("nullValue", nullValue) resultSetAction.setUser(user) resultSetAction diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/UploadFileAction.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/UploadFileAction.scala new file mode 100644 index 0000000000..4248a9c7c6 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/request/UploadFileAction.scala @@ -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.ujes.client.request + +import org.apache.linkis.httpclient.request.{BinaryBody, GetAction, UploadAction} +import org.apache.linkis.ujes.client.exception.UJESClientBuilderException + +import org.apache.http.entity.ContentType + +import java.io.{File, FileInputStream} +import java.util + +import scala.collection.JavaConverters._ + +class UploadFileAction extends GetAction with UploadAction with UJESJobAction { + override def suffixURLs: Array[String] = Array("filesystem", "upload") + + override val files: util.Map[String, String] = new util.HashMap[String, String]() + + override val binaryBodies: util.List[BinaryBody] = new util.ArrayList[BinaryBody](0) + +} + +object UploadFileAction { + def builder(): Builder = new Builder + + class Builder private[UploadFileAction] { + private var user: String = _ + private var path: String = _ + private var uploadFiles: util.List[File] = new util.ArrayList[File](0) + + def setUser(user: String): Builder = { + this.user = user + this + } + + def setPath(path: String): Builder = { + this.path = path + this + } + + def addFile(file: File): Builder = { + this.uploadFiles.add(file) + this + } + + def build(): UploadFileAction = { + val uploadFileAction = new UploadFileAction + if (user == null) throw new UJESClientBuilderException("user is needed!") + if (path == null) throw new UJESClientBuilderException("path is needed!") + + uploadFileAction.setUser(user) + uploadFileAction.setParameter("path", path) + uploadFiles.asScala.foreach { file => + println(String.format("=============== upload file ========== %s ", file.getAbsolutePath)) + uploadFileAction.binaryBodies.add( + BinaryBody + .apply("file", new FileInputStream(file), file.getName, ContentType.MULTIPART_FORM_DATA) + ) + } + + uploadFileAction + } + + } + +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/CreateNewDirResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/CreateNewDirResult.scala new file mode 100644 index 0000000000..0871f4042e --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/CreateNewDirResult.scala @@ -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.ujes.client.response + +import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult +import org.apache.linkis.httpclient.dws.response.DWSResult +import org.apache.linkis.ujes.client.request.UserAction + +@DWSHttpMessageResult("/api/rest_j/v\\d+/filesystem/createNewDir") +class CreateNewDirResult extends DWSResult with UserAction {} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/IsPathExistResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/IsPathExistResult.scala new file mode 100644 index 0000000000..c87cd7d2c7 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/IsPathExistResult.scala @@ -0,0 +1,29 @@ +/* + * 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.ujes.client.response + +import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult +import org.apache.linkis.httpclient.dws.response.DWSResult +import org.apache.linkis.ujes.client.request.UserAction + +import scala.beans.BeanProperty + +@DWSHttpMessageResult("/api/rest_j/v\\d+/filesystem/isExist") +class IsPathExistResult extends DWSResult with UserAction { + @BeanProperty var isExist: Boolean = _ +} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/ResultSetResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/ResultSetResult.scala index 973573f494..9051748c36 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/ResultSetResult.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/ResultSetResult.scala @@ -20,6 +20,9 @@ package org.apache.linkis.ujes.client.response import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult import org.apache.linkis.httpclient.dws.response.DWSResult import org.apache.linkis.ujes.client.request.UserAction +import org.apache.linkis.ujes.client.utils.UJESClientUtils.evaluate + +import java.util import scala.beans.BeanProperty @@ -28,6 +31,31 @@ class ResultSetResult extends DWSResult with UserAction { private var `type`: String = _ + private var metadataList: util.List[util.Map[String, String]] = _ + + private var fileContentList: util.List[util.ArrayList[_]] = _ + + def getMetadataList: util.List[util.Map[String, String]] = { + metadata.asInstanceOf[util.List[util.Map[String, String]]] + } + + def getRowList: util.List[util.ArrayList[Any]] = { + val metaData = metadata.asInstanceOf[util.List[util.Map[String, String]]] + val fileContentList = fileContent.asInstanceOf[util.List[util.ArrayList[Any]]] + for (metaDataColnum <- 1 to metaData.size()) { + val col = metaData.get(metaDataColnum - 1) + if (!col.get("dataType").equals("string")) { + for (cursor <- 1 to fileContentList.size()) { + val colDataList = fileContentList.get(cursor - 1) + var colData = colDataList.get(metaDataColnum - 1) + colData = evaluate(col.get("dataType"), colData.toString) + colDataList.set(metaDataColnum - 1, colData) + } + } + } + fileContentList + } + def setType(`type`: String): Unit = this.`type` = `type` def getType: String = `type` diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/UploadFileResult.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/UploadFileResult.scala new file mode 100644 index 0000000000..837399f2d9 --- /dev/null +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/response/UploadFileResult.scala @@ -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.ujes.client.response + +import org.apache.linkis.httpclient.dws.annotation.DWSHttpMessageResult +import org.apache.linkis.httpclient.dws.response.DWSResult +import org.apache.linkis.ujes.client.request.UserAction + +@DWSHttpMessageResult("/api/rest_j/v\\d+/filesystem/upload") +class UploadFileResult extends DWSResult with UserAction {} diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala index 9615a89bc0..e640b3d7b5 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala @@ -17,8 +17,15 @@ package org.apache.linkis.ujes.client.utils +import org.apache.linkis.ujes.client.exception.UJESClientBuilderException import org.apache.linkis.ujes.client.request.JobExecuteAction.{EngineType, RunType} + +import java.util +import java.util.Locale + +import com.google.gson.{Gson, JsonObject} + object UJESClientUtils { def toEngineType(engineType: String): EngineType = engineType match { @@ -48,4 +55,33 @@ object UJESClientUtils { case _ => EngineType.SPARK.SQL } + def evaluate(dataType: String, value: String): Any = { + if (value == null || value.equals("null") || value.equals("NULL") || value.equals("Null")) { + dataType.toLowerCase(Locale.getDefault) match { + case "string" | "char" | "varchar" | "nvarchar" => value + case _ => null + } + } else { + dataType.toLowerCase(Locale.getDefault) match { + case null => throw new UJESClientBuilderException("data is empty") + case "char" | "varchar" | "nvarchar" | "string" => value + case "short" => value.toShort + case "int" => value.toInt + case "long" => value.toLong + case "float" => value.toFloat + case "double" => value.toDouble + case "boolean" => value.toBoolean + case "byte" => value.toByte + case "timestamp" => value + case "date" => value + case "bigint" => value.toLong + case "decimal" => value.toDouble + case "array" => new Gson().fromJson(value, classOf[util.ArrayList[Object]]) + case "map" => new Gson().fromJson(value, classOf[util.HashMap[Object, Object]]) + case "struct" => new Gson().fromJson(value, classOf[JsonObject]) + case _ => value + } + } + } + } From 63e06aa478d2cb0613988702d1f9738d5b7cf01d Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 18:23:59 +0800 Subject: [PATCH 02/21] Engine support marking as unhealthy to exit gracefully --- .../DefaultExecutorHeartbeatService.scala | 32 +++++++++++++++-- .../service/DefaultManagerService.scala | 3 ++ .../utils/AccessableExecutorUtils.scala | 34 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/utils/AccessableExecutorUtils.scala diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultExecutorHeartbeatService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultExecutorHeartbeatService.scala index ea3248ba6d..ff8e6666d1 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultExecutorHeartbeatService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultExecutorHeartbeatService.scala @@ -31,8 +31,13 @@ import org.apache.linkis.engineconn.core.executor.ExecutorManager import org.apache.linkis.engineconn.executor.entity.{Executor, ResourceExecutor, SensibleExecutor} import org.apache.linkis.engineconn.executor.listener.ExecutorListenerBusContext import org.apache.linkis.engineconn.executor.service.ManagerService -import org.apache.linkis.manager.common.entity.enumeration.NodeStatus -import org.apache.linkis.manager.common.protocol.node.{NodeHeartbeatMsg, NodeHeartbeatRequest} +import org.apache.linkis.manager.common.entity.enumeration.{NodeHealthy, NodeStatus} +import org.apache.linkis.manager.common.entity.metrics.NodeHealthyInfo +import org.apache.linkis.manager.common.protocol.node.{ + NodeHealthyRequest, + NodeHeartbeatMsg, + NodeHeartbeatRequest +} import org.apache.linkis.rpc.Sender import org.apache.linkis.rpc.message.annotation.Receiver @@ -61,6 +66,8 @@ class DefaultExecutorHeartbeatService private val asyncListenerBusContext = ExecutorListenerBusContext.getExecutorListenerBusContext.getEngineConnAsyncListenerBus + private val healthyLock = new Object() + @PostConstruct private def init(): Unit = { asyncListenerBusContext.addListener(this) @@ -95,6 +102,16 @@ class DefaultExecutorHeartbeatService nodeHeartbeatRequest: NodeHeartbeatRequest ): NodeHeartbeatMsg = generateHeartBeatMsg(null) + @Receiver + def dealNodeHealthyRequest(nodeHealthyRequest: NodeHealthyRequest): Unit = + healthyLock synchronized { + val toHealthy = nodeHealthyRequest.getNodeHealthy + val healthyInfo: NodeHealthyInfo = nodeHealthyInfoManager.getNodeHealthyInfo() + logger.info(s"engine nodeHealthy from ${healthyInfo.getNodeHealthy} to ${toHealthy}") + nodeHealthyInfoManager.setByManager(true) + nodeHealthyInfoManager.setNodeHealthy(toHealthy) + } + override def onNodeHealthyUpdate(nodeHealthyUpdateEvent: NodeHealthyUpdateEvent): Unit = { logger.warn(s"node healthy update, tiger heartbeatReport") // val executor = ExecutorManager.getInstance.getReportExecutor @@ -139,4 +156,15 @@ class DefaultExecutorHeartbeatService nodeHeartbeatMsg } + override def setSelfUnhealthy(reason: String): Unit = healthyLock synchronized { + logger.info(s"Set self to unhealthy to automatically exit, reason: $reason") + if (EngineConnObject.isReady) { + val nodeHealthyInfo = nodeHealthyInfoManager.getNodeHealthyInfo() + if (nodeHealthyInfo.getNodeHealthy != NodeHealthy.UnHealthy) { + nodeHealthyInfoManager.setNodeHealthy(NodeHealthy.UnHealthy) + nodeHealthyInfoManager.setByManager(true) + } + } + } + } 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 bc410c7186..7d4dc3b08a 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 @@ -76,6 +76,9 @@ class DefaultManagerService extends ManagerService with Logging { override def heartbeatReport(nodeHeartbeatMsg: NodeHeartbeatMsg): Unit = { getManagerSender.send(nodeHeartbeatMsg) + if (nodeHeartbeatMsg != null && nodeHeartbeatMsg.getHealthyInfo != null) { + logger.info("report engine healthy status: {}", nodeHeartbeatMsg.getHealthyInfo) + } logger.info( "success to send engine heartbeat report to {},status: {},msg: {}", Array( diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/utils/AccessableExecutorUtils.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/utils/AccessableExecutorUtils.scala new file mode 100644 index 0000000000..9416c14f84 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/utils/AccessableExecutorUtils.scala @@ -0,0 +1,34 @@ +/* + * 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.utils + +import org.apache.linkis.DataWorkCloudApplication.getApplicationContext +import org.apache.linkis.engineconn.acessible.executor.info.DefaultNodeHealthyInfoManager +import org.apache.linkis.manager.common.entity.enumeration.NodeHealthy + +object AccessibleExecutorUtils { + + val manager: DefaultNodeHealthyInfoManager = + getApplicationContext.getBean(classOf[DefaultNodeHealthyInfoManager]) + + + def currentEngineIsUnHealthy(): Boolean = { + manager != null && manager.getNodeHealthy() == NodeHealthy.UnHealthy + } + +} From e5add910a09663cbb1ccb299dc15920aea2744a3 Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 18:24:42 +0800 Subject: [PATCH 03/21] Current Engine supports automatic exit --- .../AccessibleExecutorConfiguration.scala | 11 +++++- .../AccessibleEngineConnExecution.scala | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/conf/AccessibleExecutorConfiguration.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/conf/AccessibleExecutorConfiguration.scala index 40cf314853..0cebf5ed15 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/conf/AccessibleExecutorConfiguration.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/conf/AccessibleExecutorConfiguration.scala @@ -37,11 +37,14 @@ object AccessibleExecutorConfiguration { val ENGINECONN_LOG_SEND_SIZE = CommonVars[Int]("wds.linkis.engineconn.log.send.cache.size", 300) val ENGINECONN_MAX_FREE_TIME = - CommonVars("wds.linkis.engineconn.max.free.time", new TimeType("10m")) + CommonVars("wds.linkis.engineconn.max.free.time", new TimeType("5m")) val ENGINECONN_LOCK_CHECK_INTERVAL = CommonVars("wds.linkis.engineconn.lock.free.interval", new TimeType("3m")) + val ENGINECONN_ENABLED_LOCK_IDLE_TIME_OUT = + CommonVars("linkis.engineconn.enabled.lock.timeout.release", true) + val ENGINECONN_SUPPORT_PARALLELISM = CommonVars("wds.linkis.engineconn.support.parallelism", false) @@ -67,4 +70,10 @@ object AccessibleExecutorConfiguration { "Heartbeat status report repeated ignore, default 3ms,Negative numbers do not take effect" ).getValue + val ENGINECONN_AUTO_EXIT = + CommonVars("linkis.engineconn.support.auto.exit", false).getValue + + val ENGINECONN_AUTO_EXIT_DAYS = + CommonVars("linkis.engineconn.auto.exit.days", 7).getValue + } 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 0bd7ececef..6e6b8b5986 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 @@ -20,6 +20,7 @@ package org.apache.linkis.engineconn.acessible.executor.execution import org.apache.linkis.common.utils.{Logging, Utils} import org.apache.linkis.engineconn.acessible.executor.conf.AccessibleExecutorConfiguration import org.apache.linkis.engineconn.acessible.executor.entity.AccessibleExecutor +import org.apache.linkis.engineconn.acessible.executor.service.ExecutorHeartbeatServiceHolder import org.apache.linkis.engineconn.common.creation.EngineCreationContext import org.apache.linkis.engineconn.common.engineconn.EngineConn import org.apache.linkis.engineconn.common.execution.EngineConnExecution @@ -40,6 +41,7 @@ import org.apache.linkis.manager.common.protocol.resource.ResourceUsedProtocol import org.apache.linkis.manager.label.utils.LabelUtil import org.apache.linkis.rpc.Sender +import java.util.Random import java.util.concurrent.TimeUnit class AccessibleEngineConnExecution extends EngineConnExecution with Logging { @@ -73,6 +75,9 @@ class AccessibleEngineConnExecution extends EngineConnExecution with Logging { reportUsedResource(executor, engineCreationContext) reportLabel(executor) executorStatusChecker + if (AccessibleExecutorConfiguration.ENGINECONN_AUTO_EXIT) { + ecAutoExit() + } afterReportToLinkisManager(executor, engineCreationContext, engineConn) } @@ -140,6 +145,39 @@ class AccessibleEngineConnExecution extends EngineConnExecution with Logging { ) } + /** + * EC auto exit only support concurrent executor + */ + private def ecAutoExit(): Unit = { + logger.info(s"ec auto exit start ${System.currentTimeMillis()}") + Utils.defaultScheduler.schedule( + new Runnable { + override def run(): Unit = Utils.tryAndWarn { + ExecutorManager.getInstance.getReportExecutor match { + case executor: ConcurrentExecutor => + val rand = new Random + val minute = rand.nextInt(5) + 1 + Thread.sleep(minute * 60000L) + if (executor.hasTaskRunning()) { + ExecutorHeartbeatServiceHolder + .getDefaultHeartbeatService() + .setSelfUnhealthy(s"EC running time exceed max time") + } else { + logger.warn( + s"Executor has no task running ${executor.getId}, will be to shutdown ec" + ) + executor.tryShutdown() + } + case _ => + logger.warn(s"Executor is not a ConcurrentExecutor, do noting") + } + } + }, + AccessibleExecutorConfiguration.ENGINECONN_AUTO_EXIT_DAYS, + TimeUnit.DAYS + ) + } + def requestManagerReleaseExecutor(msg: String, nodeStatus: NodeStatus): Unit = { val engineReleaseRequest = new EngineConnReleaseRequest( Sender.getThisServiceInstance, From 434e14b75de08939e61fed2eb06352e27277172b Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 18:45:20 +0800 Subject: [PATCH 04/21] Fix engine exit hang bug --- .../linkis/common/conf/Configuration.scala | 7 +++++ .../acessible/executor/log/SendAppender.java | 19 ++++++++++++ .../info/NodeHealthyInfoManager.scala | 31 +++++++++++++++++-- .../executor/lock/EngineConnTimedLock.scala | 17 ++++++++-- .../service/DefaultAccessibleService.scala | 1 - .../service/ExecutorHeartbeatService.scala | 2 ++ 6 files changed, 70 insertions(+), 7 deletions(-) diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/conf/Configuration.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/conf/Configuration.scala index 9443f15262..5522424e08 100644 --- a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/conf/Configuration.scala +++ b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/conf/Configuration.scala @@ -65,6 +65,8 @@ object Configuration extends Logging { val JOB_HISTORY_ADMIN = CommonVars("wds.linkis.jobhistory.admin", "hadoop") + val JOB_HISTORY_DEPARTMENT_ADMIN = CommonVars("wds.linkis.jobhistory.department.admin", "hadoop") + // Only the specified token has permission to call some api val GOVERNANCE_STATION_ADMIN_TOKEN_STARTWITH = "ADMIN-" @@ -124,6 +126,11 @@ object Configuration extends Logging { .exists(username.equalsIgnoreCase) } + def isDepartmentAdmin(username: String): Boolean = { + val departmentAdminUsers = JOB_HISTORY_DEPARTMENT_ADMIN.getHotValue.split(",") + departmentAdminUsers.exists(username.equalsIgnoreCase) + } + def getJobHistoryAdmin(): Array[String] = { val adminUsers = GOVERNANCE_STATION_ADMIN.getHotValue.split(",") val historyAdminUsers = JOB_HISTORY_ADMIN.getHotValue.split(",") diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/log/SendAppender.java b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/log/SendAppender.java index cde56ca03a..b27464285d 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/log/SendAppender.java +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/java/org/apache/linkis/engineconn/acessible/executor/log/SendAppender.java @@ -18,9 +18,12 @@ package org.apache.linkis.engineconn.acessible.executor.log; import org.apache.linkis.engineconn.acessible.executor.conf.AccessibleExecutorConfiguration; +import org.apache.linkis.engineconn.common.conf.EngineConnConf; +import org.apache.linkis.engineconn.common.conf.EngineConnConstant; import org.apache.linkis.engineconn.executor.listener.EngineConnSyncListenerBus; import org.apache.linkis.engineconn.executor.listener.ExecutorListenerBusContext; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; @@ -34,6 +37,8 @@ import org.apache.logging.log4j.core.layout.PatternLayout; import java.io.Serializable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -91,6 +96,7 @@ public void append(LogEvent event) { } } if (!flag) { + logStr = matchLog(logStr); logCache.cacheLog(logStr); } } else { @@ -113,4 +119,17 @@ public static SendAppender createAppender( } return new SendAppender(name, filter, layout, ignoreExceptions); } + + public String matchLog(String logLine) { + String yarnUrl = EngineConnConf.JOB_YARN_TASK_URL().getValue(); + if (StringUtils.isNotBlank(yarnUrl)) { + Matcher hiveMatcher = Pattern.compile(EngineConnConstant.hiveLogReg()).matcher(logLine); + if (hiveMatcher.find()) { + logLine = + hiveMatcher.replaceAll( + EngineConnConstant.YARN_LOG_URL() + yarnUrl + hiveMatcher.group(1)); + } + } + return logLine; + } } diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/info/NodeHealthyInfoManager.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/info/NodeHealthyInfoManager.scala index 4365d5881d..98f88508e8 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/info/NodeHealthyInfoManager.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/info/NodeHealthyInfoManager.scala @@ -20,7 +20,7 @@ package org.apache.linkis.engineconn.acessible.executor.info import org.apache.linkis.common.utils.Logging import org.apache.linkis.engineconn.acessible.executor.entity.AccessibleExecutor import org.apache.linkis.engineconn.core.executor.ExecutorManager -import org.apache.linkis.manager.common.entity.enumeration.NodeStatus +import org.apache.linkis.manager.common.entity.enumeration.{NodeHealthy, NodeStatus} import org.apache.linkis.manager.common.entity.metrics.NodeHealthyInfo import org.springframework.stereotype.Component @@ -29,20 +29,45 @@ trait NodeHealthyInfoManager { def getNodeHealthyInfo(): NodeHealthyInfo + def setNodeHealthy(healthy: NodeHealthy): Unit + + def getNodeHealthy(): NodeHealthy + + def setByManager(setByManager: Boolean): Unit + } @Component class DefaultNodeHealthyInfoManager extends NodeHealthyInfoManager with Logging { + private var healthy: NodeHealthy = NodeHealthy.Healthy + + private var setByManager: Boolean = false + override def getNodeHealthyInfo(): NodeHealthyInfo = { val nodeHealthyInfo = new NodeHealthyInfo nodeHealthyInfo.setMsg("") - nodeHealthyInfo.setNodeHealthy( + + /** If it is actively set by the manager, then the manager setting shall prevail */ + val newHealthy: NodeHealthy = if (this.setByManager) { + this.healthy + } else { NodeStatus.isEngineNodeHealthy( ExecutorManager.getInstance.getReportExecutor.asInstanceOf[AccessibleExecutor].getStatus ) - ) + } + logger.info("current node healthy status is {}", newHealthy) + nodeHealthyInfo.setNodeHealthy(newHealthy) nodeHealthyInfo } + override def setNodeHealthy(healthy: NodeHealthy): Unit = { + this.healthy = healthy + } + + override def setByManager(setByManager: Boolean): Unit = { + this.setByManager = setByManager + } + + override def getNodeHealthy(): NodeHealthy = this.healthy } diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/lock/EngineConnTimedLock.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/lock/EngineConnTimedLock.scala index af4d1eb017..bb39545091 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/lock/EngineConnTimedLock.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/lock/EngineConnTimedLock.scala @@ -27,6 +27,7 @@ import org.apache.linkis.engineconn.acessible.executor.listener.event.{ ExecutorStatusChangedEvent, ExecutorUnLockEvent } +import org.apache.linkis.engineconn.core.EngineConnObject import org.apache.linkis.engineconn.core.executor.ExecutorManager import org.apache.linkis.engineconn.executor.entity.SensibleExecutor import org.apache.linkis.engineconn.executor.listener.ExecutorListenerBusContext @@ -44,6 +45,10 @@ class EngineConnTimedLock(private var timeout: Long) var releaseTask: ScheduledFuture[_] = null var lastLockTime: Long = 0 + val idleTimeLockOut = AccessibleExecutorConfiguration.ENGINECONN_LOCK_CHECK_INTERVAL + .getValue(EngineConnObject.getEngineCreationContext.getOptions) + .toLong + override def acquire(executor: AccessibleExecutor): Unit = { lock.acquire() lastLockTime = System.currentTimeMillis() @@ -105,7 +110,9 @@ class EngineConnTimedLock(private var timeout: Long) isAcquired() && NodeStatus.Idle == reportExecutor.getStatus && isExpired() ) { // unlockCallback depends on lockedBy, so lockedBy cannot be set null before unlockCallback - logger.info(s"Lock : [${lock.toString} was released due to timeout.") + logger.info( + s"Lock : [${lock.toString} was released due to timeout. idleTimeLockOut $idleTimeLockOut" + ) release() } else if (isAcquired() && NodeStatus.Busy == reportExecutor.getStatus) { lastLockTime = System.currentTimeMillis() @@ -116,7 +123,7 @@ class EngineConnTimedLock(private var timeout: Long) } }, 3000, - AccessibleExecutorConfiguration.ENGINECONN_LOCK_CHECK_INTERVAL.getValue.toLong, + idleTimeLockOut, TimeUnit.MILLISECONDS ) logger.info("Add scheduled timeout task.") @@ -131,7 +138,11 @@ class EngineConnTimedLock(private var timeout: Long) override def isExpired(): Boolean = { if (lastLockTime == 0) return false if (timeout <= 0) return false - System.currentTimeMillis() - lastLockTime > timeout + if (AccessibleExecutorConfiguration.ENGINECONN_ENABLED_LOCK_IDLE_TIME_OUT.getValue) { + System.currentTimeMillis() - lastLockTime > idleTimeLockOut + } else { + System.currentTimeMillis() - lastLockTime > timeout + } } override def numOfPending(): Int = { diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultAccessibleService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultAccessibleService.scala index 8ef944fc9c..97a9cab5da 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultAccessibleService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/DefaultAccessibleService.scala @@ -113,7 +113,6 @@ class DefaultAccessibleService extends AccessibleService with Logging { logger.info("Reported status shuttingDown to manager.") Utils.tryQuietly(Thread.sleep(2000)) shutDownHooked = true - ShutdownHook.getShutdownHook.notifyStop() } override def stopExecutor: Unit = { diff --git a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/ExecutorHeartbeatService.scala b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/ExecutorHeartbeatService.scala index 7abcbe8dcf..77344921e3 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/ExecutorHeartbeatService.scala +++ b/linkis-computation-governance/linkis-engineconn/linkis-engineconn-executor/accessible-executor/src/main/scala/org/apache/linkis/engineconn/acessible/executor/service/ExecutorHeartbeatService.scala @@ -33,6 +33,8 @@ trait ExecutorHeartbeatService { def dealNodeHeartbeatRequest(nodeHeartbeatRequest: NodeHeartbeatRequest): NodeHeartbeatMsg + def setSelfUnhealthy(reason: String): Unit + } object ExecutorHeartbeatServiceHolder { From 787eb47a5502035b843f7e148d1e7e5aa8fe29b3 Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 22:18:13 +0800 Subject: [PATCH 05/21] add ec HookExecuteException --- .../ujes/client/utils/UJESClientUtils.scala | 1 - .../monitor/TimingMonitorService.java | 6 +-- .../exception/HookExecuteException.java | 37 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/executor/exception/HookExecuteException.java diff --git a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala index e640b3d7b5..28f4b46b9b 100644 --- a/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala +++ b/linkis-computation-governance/linkis-client/linkis-computation-client/src/main/scala/org/apache/linkis/ujes/client/utils/UJESClientUtils.scala @@ -20,7 +20,6 @@ package org.apache.linkis.ujes.client.utils import org.apache.linkis.ujes.client.exception.UJESClientBuilderException import org.apache.linkis.ujes.client.request.JobExecuteAction.{EngineType, RunType} - import java.util import java.util.Locale diff --git a/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/concurrent/monitor/TimingMonitorService.java b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/concurrent/monitor/TimingMonitorService.java index a84f581153..21d28e2d9e 100644 --- a/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/concurrent/monitor/TimingMonitorService.java +++ b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/concurrent/monitor/TimingMonitorService.java @@ -55,7 +55,7 @@ public class TimingMonitorService implements InitializingBean, Runnable { @Override public void afterPropertiesSet() throws Exception { - if ((Boolean) AccessibleExecutorConfiguration.ENGINECONN_SUPPORT_PARALLELISM().getValue()) { + if ((Boolean) (AccessibleExecutorConfiguration.ENGINECONN_SUPPORT_PARALLELISM().getValue())) { Utils.defaultScheduler() .scheduleAtFixedRate( this, 3 * 60 * 1000, MONITOR_INTERVAL.getValue().toLong(), TimeUnit.MILLISECONDS); @@ -77,7 +77,7 @@ public void run() { } } if (null == concurrentExecutor) { - LOG.warn("shell executor can not is null"); + LOG.warn("Executor can not is null"); return; } isAvailable = true; @@ -96,7 +96,7 @@ public void run() { } else { if (concurrentExecutor.isIdle()) synchronized (EXECUTOR_STATUS_LOCKER) { - LOG.info("monitor turn to executor status from busy to unlock"); + LOG.info("monitor turn to executor status from unlock to busy"); concurrentExecutor.transition(NodeStatus.Busy); } } diff --git a/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/executor/exception/HookExecuteException.java b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/executor/exception/HookExecuteException.java new file mode 100644 index 0000000000..4d1fbbfe40 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn/linkis-computation-engineconn/src/main/java/org/apache/linkis/engineconn/computation/executor/exception/HookExecuteException.java @@ -0,0 +1,37 @@ +/* + * 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.computation.executor.exception; + +import org.apache.linkis.common.exception.ExceptionLevel; +import org.apache.linkis.common.exception.LinkisRuntimeException; + +public class HookExecuteException extends LinkisRuntimeException { + + public HookExecuteException(int errCode, String desc) { + super(errCode, desc); + } + + public HookExecuteException(int errCode, String desc, String ip, int port, String serviceKind) { + super(errCode, desc, ip, port, serviceKind); + } + + @Override + public ExceptionLevel getLevel() { + return ExceptionLevel.ERROR; + } +} From fa1328b90f671b921cf200fc2a2da87131337b91 Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 22:19:50 +0800 Subject: [PATCH 06/21] add across cluster and department conf --- .../common/constant/ec/ECConstants.scala | 4 +++ .../constant/job/JobRequestConstants.scala | 4 +++ .../protocol/conf/AcrossClusterConf.scala | 26 ++++++++++++++++ .../common/protocol/conf/DepartmentConf.scala | 26 ++++++++++++++++ .../common/protocol/conf/TenantConf.scala | 11 ++++++- .../governance/common/utils/JobUtils.scala | 30 +++++++++++++++++-- 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/AcrossClusterConf.scala create mode 100644 linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/DepartmentConf.scala diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/ec/ECConstants.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/ec/ECConstants.scala index a94eadf422..c418201f43 100644 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/ec/ECConstants.scala +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/ec/ECConstants.scala @@ -74,4 +74,8 @@ object ECConstants { val EC_OPERATE_STATUS = "status" val YARN_APP_RESULT_LIST_KEY = "yarnAppResultList" + + val HIVE_OPTS = "HIVE_OPTS" + + val SPARK_SUBMIT_OPTS = "SPARK_SUBMIT_OPTS" } diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/job/JobRequestConstants.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/job/JobRequestConstants.scala index 8741c4297f..9f2879d571 100644 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/job/JobRequestConstants.scala +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/constant/job/JobRequestConstants.scala @@ -34,4 +34,8 @@ object JobRequestConstants { val JOB_DETAIL_LIST = "jobDetailList" + val JOB_SOURCE_TAGS = "job.source.tags" + + val LINKIS_JDBC_DEFAULT_DB = "linkis.jdbc.default.db" + } diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/AcrossClusterConf.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/AcrossClusterConf.scala new file mode 100644 index 0000000000..43d3c86b13 --- /dev/null +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/AcrossClusterConf.scala @@ -0,0 +1,26 @@ +/* + * 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.protocol.conf + +import org.apache.linkis.protocol.message.RequestProtocol + +trait AcrossClusterConf extends RequestProtocol + +case class AcrossClusterRequest(username: String) extends AcrossClusterConf + +case class AcrossClusterResponse(clusterName: String, queueName: String) diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/DepartmentConf.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/DepartmentConf.scala new file mode 100644 index 0000000000..dbfe3f7b74 --- /dev/null +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/DepartmentConf.scala @@ -0,0 +1,26 @@ +/* + * 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.protocol.conf + +import org.apache.linkis.protocol.message.RequestProtocol + +trait DepartmentConf extends RequestProtocol + +case class DepartmentRequest(user: String) extends DepartmentConf + +case class DepartmentResponse(user: String, departmentId: String, departmentName: String) diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/TenantConf.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/TenantConf.scala index e8d129453e..948501e772 100644 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/TenantConf.scala +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/protocol/conf/TenantConf.scala @@ -23,4 +23,13 @@ trait TenantConf extends RequestProtocol case class TenantRequest(user: String, creator: String) extends TenantConf -case class TenantResponse(user: String, creator: String, tenant: String) +case class TenantResponse(user: String, creator: String, isValid: String, tenant: String) + +case class DepartTenantRequest(creator: String, departmentId: String) extends TenantConf + +case class DepartTenantResponse( + creator: String, + departmentId: String, + isValid: String, + tenant: String +) diff --git a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/JobUtils.scala b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/JobUtils.scala index d328ebb63a..8c6522cdbb 100644 --- a/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/JobUtils.scala +++ b/linkis-computation-governance/linkis-computation-governance-common/src/main/scala/org/apache/linkis/governance/common/utils/JobUtils.scala @@ -19,8 +19,6 @@ package org.apache.linkis.governance.common.utils import org.apache.linkis.governance.common.constant.job.JobRequestConstants -import org.apache.commons.collections.MapUtils - import java.util; object JobUtils { @@ -36,7 +34,33 @@ object JobUtils { } def getJobIdFromStringMap(map: util.Map[String, String]): String = { - if (MapUtils.isNotEmpty(map)) map.getOrDefault(JobRequestConstants.JOB_ID, null) else null + if (null != map && map.containsKey(JobRequestConstants.JOB_ID)) { + val value = map.get(JobRequestConstants.JOB_ID) + if (null != value) { + return value + } + } + null + } + + def getJobSourceTagsFromStringMap(map: util.Map[String, String]): String = { + if (null != map && map.containsKey(JobRequestConstants.JOB_SOURCE_TAGS)) { + val value = map.get(JobRequestConstants.JOB_SOURCE_TAGS) + if (null != value) { + return value + } + } + null + } + + def getJobSourceTagsFromObjectMap(map: util.Map[String, Object]): String = { + if (null != map && map.containsKey(JobRequestConstants.JOB_SOURCE_TAGS)) { + val value = map.get(JobRequestConstants.JOB_SOURCE_TAGS) + if (null != value) { + return value.toString + } + } + null } } From 988069abc752b38677715261b81f0e2a3ff88127 Mon Sep 17 00:00:00 2001 From: peacewong Date: Fri, 7 Jun 2024 22:27:44 +0800 Subject: [PATCH 07/21] optimize Configuration module --- .../conf/AcrossClusterRuleKeys.java | 24 +- .../dao/AcrossClusterRuleMapper.java | 29 +- .../configuration/dao/DepartmentMapper.java | 31 ++ .../dao/DepartmentTenantMapper.java | 41 ++ .../entity/DepartmentTenantVo.java | 155 +++++++ .../configuration/entity/DepartmentVo.java | 185 ++++++++ .../linkis/configuration/entity/TenantVo.java | 13 + .../api/AcrossClusterRuleRestfulApi.java | 431 +++++++++++++++--- .../restful/api/ConfigurationRestfulApi.java | 47 +- ...estfulApi.java => TemplateRestfulApi.java} | 13 +- .../api/TenantConfigrationRestfulApi.java | 132 +++++- .../service/AcrossClusterRuleService.java | 22 +- .../service/DepartmentService.java | 27 ++ .../service/TenantConfigService.java | 14 + .../configuration/service/TenantService.java | 4 + .../impl/AcrossClusterRuleServiceImpl.java | 84 +++- .../service/impl/DepartmentServiceImpl.java | 56 +++ .../service/impl/TenantConfigServiceImpl.java | 118 ++++- .../service/impl/TenantServiceImpl.java | 33 +- .../util/{HttpsUtil.java => ClientUtil.java} | 10 +- .../configuration/util/CommonUtils.java | 43 +- .../mapper/common/DepartmentMapper.xml | 38 ++ .../mapper/mysql/AcrossClusterRuleMapper.xml | 87 +++- .../mapper/mysql/UserTenantMapper.xml | 19 +- .../configuration/conf/Configuration.scala | 3 + .../service/ConfigurationService.scala | 39 +- .../util/LabelParameterParser.scala | 6 +- 27 files changed, 1512 insertions(+), 192 deletions(-) create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentMapper.java create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentTenantMapper.java create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentTenantVo.java create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentVo.java rename linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/{TemplateManagerRestfulApi.java => TemplateRestfulApi.java} (95%) create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/DepartmentService.java create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/DepartmentServiceImpl.java rename linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/{HttpsUtil.java => ClientUtil.java} (93%) create mode 100644 linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/common/DepartmentMapper.xml diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/conf/AcrossClusterRuleKeys.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/conf/AcrossClusterRuleKeys.java index f2fee2ff1f..611c5e1d68 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/conf/AcrossClusterRuleKeys.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/conf/AcrossClusterRuleKeys.java @@ -19,25 +19,35 @@ public class AcrossClusterRuleKeys { - public static final String KEY_QUEUE_SUFFIX = "suffix"; + public static final String KEY_CROSS_QUEUE = "crossQueue"; - public static final String KEY_ACROSS_CLUSTER_QUEUE_SUFFIX = "bdap2bdp"; + public static final String KEY_PRIORITY_CLUSTER = "priorityCluster"; public static final String KEY_START_TIME = "startTime"; public static final String KEY_END_TIME = "endTime"; - public static final String KEY_CPU_THRESHOLD = "CPUThreshold"; + public static final String KEY_TARGET_CPU_THRESHOLD = "targetCPUThreshold"; - public static final String KEY_MEMORY_THRESHOLD = "MemoryThreshold"; + public static final String KEY_TARGET_MEMORY_THRESHOLD = "targetMemoryThreshold"; - public static final String KEY_CPU_PERCENTAGE_THRESHOLD = "CPUPercentageThreshold"; + public static final String KEY_TARGET_CPU_PERCENTAGE_THRESHOLD = "targetCPUPercentageThreshold"; - public static final String KEY_MEMORY_PERCENTAGE_THRESHOLD = "MemoryPercentageThreshold"; + public static final String KEY_TARGET_MEMORY_PERCENTAGE_THRESHOLD = + "targetMemoryPercentageThreshold"; + + public static final String KEY_ORIGIN_CPU_PERCENTAGE_THRESHOLD = "originCPUPercentageThreshold"; + + public static final String KEY_ORIGIN_MEMORY_PERCENTAGE_THRESHOLD = + "originMemoryPercentageThreshold"; public static final String KEY_QUEUE_RULE = "queueRule"; public static final String KEY_TIME_RULE = "timeRule"; - public static final String KEY_THRESHOLD_RULE = "thresholdRule"; + public static final String KEY_TARGET_CLUSTER_RULE = "targetClusterRule"; + + public static final String KEY_ORIGIN_CLUSTER_RULE = "originClusterRule"; + + public static final String KEY_PRIORITY_CLUSTER_RULE = "priorityClusterRule"; } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/AcrossClusterRuleMapper.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/AcrossClusterRuleMapper.java index 9dadcf918c..55c5b1ad56 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/AcrossClusterRuleMapper.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/AcrossClusterRuleMapper.java @@ -25,13 +25,22 @@ public interface AcrossClusterRuleMapper { - AcrossClusterRule getAcrossClusterRule(@Param("id") Long id); + AcrossClusterRule getAcrossClusterRule(@Param("id") Long id, @Param("username") String username); - void deleteAcrossClusterRule( - @Param("creator") String creator, @Param("username") String username); + void deleteAcrossClusterRule(@Param("id") Long id); + + void deleteAcrossClusterRuleByBatch(@Param("ids") List ids); + + void deleteAcrossClusterRuleByUsername(@Param("username") String username); + + void deleteAcrossClusterRuleByCrossQueue(@Param("crossQueue") String crossQueue); void updateAcrossClusterRule(@Param("acrossClusterRule") AcrossClusterRule acrossClusterRule); + void updateAcrossClusterRuleByBatch( + @Param("ids") List ids, + @Param("acrossClusterRule") AcrossClusterRule acrossClusterRule); + void insertAcrossClusterRule(@Param("acrossClusterRule") AcrossClusterRule acrossClusterRule); List queryAcrossClusterRuleList( @@ -39,5 +48,17 @@ List queryAcrossClusterRuleList( @Param("creator") String creator, @Param("clusterName") String clusterName); - void validAcrossClusterRule(@Param("isValid") String isValid, @Param("id") Long id); + void validAcrossClusterRule( + @Param("isValid") String isValid, @Param("id") Long id, @Param("username") String username); + + /** + * Query across cluster resource rule by username. + * + * @param username + * @return + */ + AcrossClusterRule queryAcrossClusterRuleByUserName(@Param("username") String username); + + void validAcrossClusterRuleByBatch( + @Param("ids") List ids, @Param("isValid") String isValid); } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentMapper.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentMapper.java new file mode 100644 index 0000000000..195fef6d57 --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentMapper.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.configuration.dao; + +import org.apache.linkis.configuration.entity.DepartmentVo; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface DepartmentMapper { + + DepartmentVo getDepartmentByUser(@Param("user") String user); + + List queryDepartmentList(); +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentTenantMapper.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentTenantMapper.java new file mode 100644 index 0000000000..336ad698bb --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/dao/DepartmentTenantMapper.java @@ -0,0 +1,41 @@ +/* + * 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.configuration.dao; + +import org.apache.linkis.configuration.entity.DepartmentTenantVo; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface DepartmentTenantMapper { + + void insertTenant(DepartmentTenantVo departmentTenantVo); + + void updateTenant(DepartmentTenantVo departmentTenantVo); + + List queryTenantList( + @Param("creator") String creator, + @Param("departmentId") String departmentId, + @Param("tenantValue") String tenantValue); + + void deleteTenant(@Param("id") Integer id); + + DepartmentTenantVo queryTenant( + @Param("creator") String creator, @Param("departmentId") String departmentId); +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentTenantVo.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentTenantVo.java new file mode 100644 index 0000000000..41b4d3d6a0 --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentTenantVo.java @@ -0,0 +1,155 @@ +/* + * 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.configuration.entity; + +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel +public class DepartmentTenantVo { + @ApiModelProperty("id") + private String id; + + @ApiModelProperty("creator") + private String creator; + + @ApiModelProperty("department") + private String department; + + @ApiModelProperty("departmentId") + private String departmentId; + + @ApiModelProperty("tenantValue") + private String tenantValue; + + @ApiModelProperty("createTime") + private Date createTime; + + @ApiModelProperty("updateTime") + private Date updateTime; + + @ApiModelProperty("createBy") + private String createBy; + + @ApiModelProperty("isValid") + private String isValid; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getDepartmentId() { + return departmentId; + } + + public void setDepartmentId(String departmentId) { + this.departmentId = departmentId; + } + + public String getTenantValue() { + return tenantValue; + } + + public void setTenantValue(String tenantValue) { + this.tenantValue = tenantValue; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getIsValid() { + return isValid; + } + + public void setIsValid(String isValid) { + this.isValid = isValid; + } + + @Override + public String toString() { + return "DepartmentTenantVo{" + + "id='" + + id + + '\'' + + ", creator='" + + creator + + '\'' + + ", department='" + + department + + '\'' + + ", departmentId='" + + departmentId + + '\'' + + ", tenantValue='" + + tenantValue + + '\'' + + ", createTime=" + + createTime + + ", updateTime=" + + updateTime + + ", bussinessUser='" + + createBy + + ", isValid=" + + isValid + + '\'' + + '}'; + } +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentVo.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentVo.java new file mode 100644 index 0000000000..197e3606e8 --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/DepartmentVo.java @@ -0,0 +1,185 @@ +/* + * 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.configuration.entity; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel +public class DepartmentVo { + + @ApiModelProperty("cluster_code") + private String clusterCode; + + @ApiModelProperty("user_type") + private String userType; + + @ApiModelProperty("user_name") + private String userName; + + @ApiModelProperty("org_id") + private String orgId; + + @ApiModelProperty("org_name") + private String orgName; + + @ApiModelProperty("queue_name") + private String queueName; + + @ApiModelProperty("db_name") + private String dbName; + + @ApiModelProperty("interface_user") + private String interfaceUser; + + @ApiModelProperty("is_union_analyse") + private String isUnionAnalyse; + + @ApiModelProperty("create_time") + private String createTime; + + @ApiModelProperty("user_itsm_no") + private String userItsmNo; + + public String getClusterCode() { + return clusterCode; + } + + public void setClusterCode(String clusterCode) { + this.clusterCode = clusterCode; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getOrgId() { + return orgId; + } + + public void setOrgId(String orgId) { + this.orgId = orgId; + } + + public String getOrgName() { + return orgName; + } + + public void setOrgName(String orgName) { + this.orgName = orgName; + } + + public String getQueueName() { + return queueName; + } + + public void setQueueName(String queueName) { + this.queueName = queueName; + } + + public String getDbName() { + return dbName; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + + public String getInterfaceUser() { + return interfaceUser; + } + + public void setInterfaceUser(String interfaceUser) { + this.interfaceUser = interfaceUser; + } + + public String getIsUnionAnalyse() { + return isUnionAnalyse; + } + + public void setIsUnionAnalyse(String isUnionAnalyse) { + this.isUnionAnalyse = isUnionAnalyse; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUserItsmNo() { + return userItsmNo; + } + + public void setUserItsmNo(String userItsmNo) { + this.userItsmNo = userItsmNo; + } + + @Override + public String toString() { + return "DepartmentVo{" + + "clusterCode='" + + clusterCode + + '\'' + + ", userType='" + + userType + + '\'' + + ", userName='" + + userName + + '\'' + + ", orgId='" + + orgId + + '\'' + + ", orgName='" + + orgName + + '\'' + + ", queueName='" + + queueName + + '\'' + + ", dbName='" + + dbName + + '\'' + + ", interfaceUser='" + + interfaceUser + + '\'' + + ", isUnionAnalyse='" + + isUnionAnalyse + + '\'' + + ", createTime='" + + createTime + + '\'' + + ", userItsmNo='" + + userItsmNo + + '\'' + + '}'; + } +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/TenantVo.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/TenantVo.java index c2399ff9b6..903de739e2 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/TenantVo.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/entity/TenantVo.java @@ -49,6 +49,9 @@ public class TenantVo { @ApiModelProperty("bussinessUser") private String bussinessUser; + @ApiModelProperty("isValid") + private String isValid; + public String getId() { return id; } @@ -113,6 +116,14 @@ public void setBussinessUser(String bussinessUser) { this.bussinessUser = bussinessUser; } + public String getIsValid() { + return isValid; + } + + public void setIsValid(String isValid) { + this.isValid = isValid; + } + @Override public String toString() { return "TenantVo{" @@ -137,6 +148,8 @@ public String toString() { + '\'' + ", bussinessUser='" + bussinessUser + + ", isValid=" + + isValid + '\'' + '}'; } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/AcrossClusterRuleRestfulApi.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/AcrossClusterRuleRestfulApi.java index 3a01c86060..ea66c08e94 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/AcrossClusterRuleRestfulApi.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/AcrossClusterRuleRestfulApi.java @@ -31,6 +31,8 @@ import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import io.swagger.annotations.Api; @@ -54,16 +56,15 @@ public class AcrossClusterRuleRestfulApi { notes = "valid acrossClusterRule", response = Message.class) @ApiImplicitParams({ - @ApiImplicitParam(name = "req", dataType = "HttpServletRequest", value = "req"), @ApiImplicitParam(name = "id", dataType = "Integer", value = "id"), @ApiImplicitParam(name = "isValid", dataType = "String", value = "isValid"), }) @RequestMapping(path = "/isValid", method = RequestMethod.PUT) public Message isValidRule(HttpServletRequest req, @RequestBody Map json) { String operationUser = ModuleUserUtils.getOperationUser(req, "execute valid acrossClusterRule"); + String username = null; if (!Configuration.isAdmin(operationUser)) { - return Message.error( - "Failed to valid acrossClusterRule List,msg: only administrators can configure"); + username = operationUser; } Integer idInt = (Integer) json.get("id"); @@ -71,13 +72,53 @@ public Message isValidRule(HttpServletRequest req, @RequestBody Map json) { + String operationUser = ModuleUserUtils.getOperationUser(req, "execute valid acrossClusterRule"); + if (!Configuration.isAdmin(operationUser)) { + return Message.error( + "Failed to valid acrossClusterRule batch, msg: only administrators can configure"); + } + + @SuppressWarnings("unchecked") + ArrayList ids = (ArrayList) json.get("ids"); + List ruleIds = new ArrayList<>(); + for (Integer id : ids) { + ruleIds.add(id.longValue()); + } + + String isValid = (String) json.get("isValid"); + + if (StringUtils.isBlank(isValid)) { + return Message.error("Failed to valid acrossClusterRule, Illegal Input Param: isValid"); + } + + try { + acrossClusterRuleService.validAcrossClusterRuleByBatch(ruleIds, isValid); + } catch (Exception e) { + log.info("valid acrossClusterRule failed: ", e); return Message.error("valid acrossClusterRule failed"); } @@ -89,10 +130,11 @@ public Message isValidRule(HttpServletRequest req, @RequestBody Map resultMap = null; try { resultMap = acrossClusterRuleService.queryAcrossClusterRuleList( creator, username, clusterName, pageNow, pageSize); } catch (Exception e) { - log.info("query acrossClusterRule List failed:" + e.getMessage()); + log.info("query acrossClusterRule List failed: ", e); return Message.error("query acrossClusterRule List failed"); } @@ -135,15 +180,11 @@ public Message queryAcrossClusterRuleList( notes = "delete acrossClusterRule", response = Message.class) @ApiImplicitParams({ - @ApiImplicitParam(name = "req", dataType = "HttpServletRequest", value = "req"), - @ApiImplicitParam(name = "creator", dataType = "String", value = "creator"), - @ApiImplicitParam(name = "username", dataType = "String", value = "username"), + @ApiImplicitParam(name = "id", dataType = "Integer", value = "id"), }) @RequestMapping(path = "/delete", method = RequestMethod.DELETE) public Message deleteAcrossClusterRule( - HttpServletRequest req, - @RequestParam(value = "creator", required = false) String creator, - @RequestParam(value = "username", required = false) String username) { + HttpServletRequest req, @RequestParam(value = "id", required = false) Integer id) { String operationUser = ModuleUserUtils.getOperationUser(req, "execute delete acrossClusterRule"); if (!Configuration.isAdmin(operationUser)) { @@ -151,26 +192,120 @@ public Message deleteAcrossClusterRule( "Failed to delete acrossClusterRule,msg: only administrators can configure"); } - if (StringUtils.isBlank(creator) || StringUtils.isBlank(username)) { - return Message.error("Failed to delete acrossClusterRule: Illegal Input Param"); + try { + acrossClusterRuleService.deleteAcrossClusterRule(id.longValue()); + } catch (Exception e) { + log.info("delete acrossClusterRule failed: ", e); + return Message.error("delete acrossClusterRule failed"); + } + + return Message.ok(); + } + + @ApiOperation( + value = "delete acrossClusterRule by batch", + notes = "delete acrossClusterRule by batch", + response = Message.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "ids", dataType = "List", value = "ids"), + }) + @RequestMapping(path = "/deleteByBatch", method = RequestMethod.PUT) + public Message deleteAcrossClusterRuleByBatch( + HttpServletRequest req, @RequestBody Map json) { + String operationUser = + ModuleUserUtils.getOperationUser(req, "execute delete acrossClusterRule"); + if (!Configuration.isAdmin(operationUser)) { + return Message.error( + "Failed to delete acrossClusterRule,msg: only administrators can configure"); + } + + @SuppressWarnings("unchecked") + ArrayList ids = (ArrayList) json.get("ids"); + List ruleIds = new ArrayList<>(); + for (Integer id : ids) { + ruleIds.add(id.longValue()); } try { - acrossClusterRuleService.deleteAcrossClusterRule(creator, username); + acrossClusterRuleService.deleteAcrossClusterRuleByBatch(ruleIds); } catch (Exception e) { - log.info("delete acrossClusterRule failed:" + e.getMessage()); + log.info("delete acrossClusterRule failed: ", e); return Message.error("delete acrossClusterRule failed"); } return Message.ok(); } + @ApiOperation( + value = "delete acrossClusterRule", + notes = "delete acrossClusterRule", + response = Message.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "username", dataType = "String", value = "username"), + }) + @RequestMapping(path = "/deleteByUsername", method = RequestMethod.DELETE) + public Message deleteAcrossClusterRuleByUsername( + HttpServletRequest req, @RequestParam(value = "username", required = false) String username) { + String operationUser = + ModuleUserUtils.getOperationUser(req, "execute delete acrossClusterRule"); + if (!Configuration.isAdmin(operationUser)) { + return Message.error( + "Failed to delete acrossClusterRule,msg: only administrators can configure"); + } + + if (StringUtils.isBlank(username)) { + return Message.error("Failed to delete acrossClusterRule, Illegal Input Param: username"); + } + + try { + acrossClusterRuleService.deleteAcrossClusterRuleByUsername(username); + } catch (Exception e) { + log.info("delete acrossClusterRule failed:", e); + return Message.error("delete acrossClusterRule failed, username is: " + username); + } + + return Message.ok(); + } + + @ApiOperation( + value = "delete acrossClusterRule", + notes = "delete acrossClusterRule", + response = Message.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "crossQueue", dataType = "String", value = "crossQueue"), + }) + @RequestMapping(path = "/deleteByCrossQueue", method = RequestMethod.DELETE) + public Message deleteAcrossClusterRuleByCrossQueue( + HttpServletRequest req, + @RequestParam(value = "crossQueue", required = false) String crossQueue) { + String operationUser = + ModuleUserUtils.getOperationUser(req, "execute delete acrossClusterRule"); + if (!Configuration.isAdmin(operationUser)) { + return Message.error( + "Failed to delete acrossClusterRule,msg: only administrators can configure"); + } + + if (StringUtils.isBlank(crossQueue)) { + return Message.error( + "Failed to delete acrossClusterRule, Illegal Input Param: " + crossQueue); + } + + try { + acrossClusterRuleService.deleteAcrossClusterRuleByCrossQueue( + CommonUtils.concatQueue(crossQueue)); + } catch (Exception e) { + log.info("delete acrossClusterRule failed:", e); + return Message.error("delete acrossClusterRule failed, crossQueue is: " + crossQueue); + } + + return Message.ok(); + } + @ApiOperation( value = "update acrossClusterRule", notes = "update acrossClusterRule ", response = Message.class) @ApiImplicitParams({ - @ApiImplicitParam(name = "req", dataType = "HttpServletRequest", value = "req"), @ApiImplicitParam(name = "id", dataType = "Integer", value = "id"), @ApiImplicitParam(name = "clusterName", dataType = "String", value = "clusterName"), @ApiImplicitParam(name = "creator", dataType = "String", value = "creator"), @@ -178,16 +313,32 @@ public Message deleteAcrossClusterRule( @ApiImplicitParam(name = "isValid", dataType = "String", value = "isValid"), @ApiImplicitParam(name = "startTime", dataType = "String", value = "startTime"), @ApiImplicitParam(name = "endTime", dataType = "String", value = "endTime"), - @ApiImplicitParam(name = "CPUThreshold", dataType = "String", value = "CPUThreshold"), - @ApiImplicitParam(name = "MemoryThreshold", dataType = "String", value = "MemoryThreshold"), + @ApiImplicitParam(name = "crossQueue", dataType = "String", value = "crossQueue"), + @ApiImplicitParam(name = "priorityCluster", dataType = "String", value = "priorityCluster"), + @ApiImplicitParam( + name = "targetCPUThreshold", + dataType = "String", + value = "targetCPUThreshold"), + @ApiImplicitParam( + name = "targetMemoryThreshold", + dataType = "String", + value = "targetMemoryThreshold"), @ApiImplicitParam( - name = "CPUPercentageThreshold", + name = "originCPUPercentageThreshold", dataType = "String", - value = "CPUPercentageThreshold"), + value = "originCPUPercentageThreshold"), @ApiImplicitParam( - name = "MemoryPercentageThreshold", + name = "originMemoryPercentageThreshold", dataType = "String", - value = "MemoryPercentageThreshold"), + value = "originMemoryPercentageThreshold"), + @ApiImplicitParam( + name = "targetCPUPercentageThreshold", + dataType = "String", + value = "targetCPUPercentageThreshold"), + @ApiImplicitParam( + name = "targetMemoryPercentageThreshold", + dataType = "String", + value = "targetMemoryPercentageThreshold"), }) @RequestMapping(path = "/update", method = RequestMethod.PUT) public Message updateAcrossClusterRule( @@ -207,21 +358,29 @@ public Message updateAcrossClusterRule( String isValid = (String) json.get("isValid"); String startTime = (String) json.get("startTime"); String endTime = (String) json.get("endTime"); - String CPUThreshold = (String) json.get("CPUThreshold"); - String MemoryThreshold = (String) json.get("MemoryThreshold"); - String CPUPercentageThreshold = (String) json.get("CPUPercentageThreshold"); - String MemoryPercentageThreshold = (String) json.get("MemoryPercentageThreshold"); + String crossQueue = (String) json.get("crossQueue"); + String priorityCluster = (String) json.get("priorityCluster"); + String targetCPUThreshold = (String) json.get("targetCPUThreshold"); + String targetMemoryThreshold = (String) json.get("targetMemoryThreshold"); + String targetCPUPercentageThreshold = (String) json.get("targetCPUPercentageThreshold"); + String targetMemoryPercentageThreshold = (String) json.get("targetMemoryPercentageThreshold"); + String originCPUPercentageThreshold = (String) json.get("originCPUPercentageThreshold"); + String originMemoryPercentageThreshold = (String) json.get("originMemoryPercentageThreshold"); if (StringUtils.isBlank(clusterName) || StringUtils.isBlank(creator) || StringUtils.isBlank(username) || StringUtils.isBlank(isValid) || StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime) - || StringUtils.isBlank(CPUThreshold) - || StringUtils.isBlank(MemoryThreshold) - || StringUtils.isBlank(CPUPercentageThreshold) - || StringUtils.isBlank(MemoryPercentageThreshold)) { - return Message.error("Failed to add acrossClusterRule: Illegal Input Param"); + || StringUtils.isBlank(crossQueue) + || StringUtils.isBlank(priorityCluster) + || StringUtils.isBlank(targetCPUThreshold) + || StringUtils.isBlank(targetMemoryThreshold) + || StringUtils.isBlank(targetCPUPercentageThreshold) + || StringUtils.isBlank(targetMemoryPercentageThreshold) + || StringUtils.isBlank(originCPUPercentageThreshold) + || StringUtils.isBlank(originMemoryPercentageThreshold)) { + return Message.error("Failed to add acrossClusterRule, Illegal Input Param"); } try { @@ -229,10 +388,14 @@ public Message updateAcrossClusterRule( CommonUtils.ruleMap2String( startTime, endTime, - CPUThreshold, - MemoryThreshold, - CPUPercentageThreshold, - MemoryPercentageThreshold); + crossQueue, + priorityCluster, + targetCPUThreshold, + targetMemoryThreshold, + targetCPUPercentageThreshold, + targetMemoryPercentageThreshold, + originCPUPercentageThreshold, + originMemoryPercentageThreshold); AcrossClusterRule acrossClusterRule = new AcrossClusterRule(); acrossClusterRule.setId(id); acrossClusterRule.setClusterName(clusterName.toLowerCase()); @@ -243,8 +406,119 @@ public Message updateAcrossClusterRule( acrossClusterRule.setIsValid(isValid); acrossClusterRuleService.updateAcrossClusterRule(acrossClusterRule); } catch (Exception e) { - log.info("update acrossClusterRule failed:" + e.getMessage()); - return Message.error("update acrossClusterRule failed:history already exist"); + log.info("update acrossClusterRule failed:", e); + return Message.error("update acrossClusterRule failed, rule already exits"); + } + return Message.ok(); + } + + @ApiOperation( + value = "update acrossClusterRule by batch", + notes = "update acrossClusterRule by batch", + response = Message.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "ids", dataType = "List", value = "ids"), + @ApiImplicitParam(name = "clusterName", dataType = "String", value = "clusterName"), + @ApiImplicitParam(name = "creator", dataType = "String", value = "creator"), + @ApiImplicitParam(name = "isValid", dataType = "String", value = "isValid"), + @ApiImplicitParam(name = "startTime", dataType = "String", value = "startTime"), + @ApiImplicitParam(name = "endTime", dataType = "String", value = "endTime"), + @ApiImplicitParam(name = "crossQueue", dataType = "String", value = "crossQueue"), + @ApiImplicitParam(name = "priorityCluster", dataType = "String", value = "priorityCluster"), + @ApiImplicitParam( + name = "targetCPUThreshold", + dataType = "String", + value = "targetCPUThreshold"), + @ApiImplicitParam( + name = "targetMemoryThreshold", + dataType = "String", + value = "targetMemoryThreshold"), + @ApiImplicitParam( + name = "originCPUPercentageThreshold", + dataType = "String", + value = "originCPUPercentageThreshold"), + @ApiImplicitParam( + name = "originMemoryPercentageThreshold", + dataType = "String", + value = "originMemoryPercentageThreshold"), + @ApiImplicitParam( + name = "targetCPUPercentageThreshold", + dataType = "String", + value = "targetCPUPercentageThreshold"), + @ApiImplicitParam( + name = "targetMemoryPercentageThreshold", + dataType = "String", + value = "targetMemoryPercentageThreshold"), + }) + @RequestMapping(path = "/updateByBatch", method = RequestMethod.PUT) + public Message updateAcrossClusterRuleByBatch( + HttpServletRequest req, @RequestBody Map json) { + String operationUser = + ModuleUserUtils.getOperationUser(req, "execute update acrossClusterRule"); + if (!Configuration.isAdmin(operationUser)) { + return Message.error( + "Failed to update acrossClusterRule,msg: only administrators can configure"); + } + + @SuppressWarnings("unchecked") + ArrayList ids = (ArrayList) json.get("ids"); + List ruleIds = new ArrayList<>(); + for (Integer id : ids) { + ruleIds.add(id.longValue()); + } + + String clusterName = (String) json.get("clusterName"); + String creator = (String) json.get("creator"); + String isValid = (String) json.get("isValid"); + String startTime = (String) json.get("startTime"); + String endTime = (String) json.get("endTime"); + String crossQueue = (String) json.get("crossQueue"); + String priorityCluster = (String) json.get("priorityCluster"); + String targetCPUThreshold = (String) json.get("targetCPUThreshold"); + String targetMemoryThreshold = (String) json.get("targetMemoryThreshold"); + String targetCPUPercentageThreshold = (String) json.get("targetCPUPercentageThreshold"); + String targetMemoryPercentageThreshold = (String) json.get("targetMemoryPercentageThreshold"); + String originCPUPercentageThreshold = (String) json.get("originCPUPercentageThreshold"); + String originMemoryPercentageThreshold = (String) json.get("originMemoryPercentageThreshold"); + if (StringUtils.isBlank(clusterName) + || StringUtils.isBlank(creator) + || StringUtils.isBlank(isValid) + || StringUtils.isBlank(startTime) + || StringUtils.isBlank(endTime) + || StringUtils.isBlank(crossQueue) + || StringUtils.isBlank(priorityCluster) + || StringUtils.isBlank(targetCPUThreshold) + || StringUtils.isBlank(targetMemoryThreshold) + || StringUtils.isBlank(targetCPUPercentageThreshold) + || StringUtils.isBlank(targetMemoryPercentageThreshold) + || StringUtils.isBlank(originCPUPercentageThreshold) + || StringUtils.isBlank(originMemoryPercentageThreshold)) { + return Message.error("Failed to add acrossClusterRule, Illegal Input Param"); + } + + try { + String rules = + CommonUtils.ruleMap2String( + startTime, + endTime, + crossQueue, + priorityCluster, + targetCPUThreshold, + targetMemoryThreshold, + targetCPUPercentageThreshold, + targetMemoryPercentageThreshold, + originCPUPercentageThreshold, + originMemoryPercentageThreshold); + AcrossClusterRule acrossClusterRule = new AcrossClusterRule(); + acrossClusterRule.setClusterName(clusterName.toLowerCase()); + acrossClusterRule.setCreator(creator); + acrossClusterRule.setUpdateBy(operationUser); + acrossClusterRule.setRules(rules); + acrossClusterRule.setIsValid(isValid); + acrossClusterRuleService.updateAcrossClusterRuleByBatch(ruleIds, acrossClusterRule); + } catch (Exception e) { + log.info("update acrossClusterRule failed:", e); + return Message.error("update acrossClusterRule failed, rule already exits"); } return Message.ok(); } @@ -254,23 +528,38 @@ public Message updateAcrossClusterRule( notes = "add acrossClusterRule ", response = Message.class) @ApiImplicitParams({ - @ApiImplicitParam(name = "req", dataType = "HttpServletRequest", value = "req"), @ApiImplicitParam(name = "clusterName", dataType = "String", value = "clusterName"), @ApiImplicitParam(name = "creator", dataType = "String", value = "creator"), @ApiImplicitParam(name = "username", dataType = "String", value = "username"), @ApiImplicitParam(name = "isValid", dataType = "String", value = "isValid"), @ApiImplicitParam(name = "startTime", dataType = "String", value = "startTime"), @ApiImplicitParam(name = "endTime", dataType = "String", value = "endTime"), - @ApiImplicitParam(name = "CPUThreshold", dataType = "String", value = "CPUThreshold"), - @ApiImplicitParam(name = "MemoryThreshold", dataType = "String", value = "MemoryThreshold"), + @ApiImplicitParam(name = "crossQueue", dataType = "String", value = "crossQueue"), + @ApiImplicitParam(name = "priorityCluster", dataType = "String", value = "priorityCluster"), + @ApiImplicitParam( + name = "targetCPUThreshold", + dataType = "String", + value = "targetCPUThreshold"), + @ApiImplicitParam( + name = "targetMemoryThreshold", + dataType = "String", + value = "targetMemoryThreshold"), + @ApiImplicitParam( + name = "originCPUPercentageThreshold", + dataType = "String", + value = "originCPUPercentageThreshold"), + @ApiImplicitParam( + name = "originMemoryPercentageThreshold", + dataType = "String", + value = "originMemoryPercentageThreshold"), @ApiImplicitParam( - name = "CPUPercentageThreshold", + name = "targetCPUPercentageThreshold", dataType = "String", - value = "CPUPercentageThreshold"), + value = "targetCPUPercentageThreshold"), @ApiImplicitParam( - name = "MemoryPercentageThreshold", + name = "targetMemoryPercentageThreshold", dataType = "String", - value = "MemoryPercentageThreshold"), + value = "targetMemoryPercentageThreshold"), }) @RequestMapping(path = "/add", method = RequestMethod.POST) public Message insertAcrossClusterRule( @@ -287,21 +576,29 @@ public Message insertAcrossClusterRule( String isValid = (String) json.get("isValid"); String startTime = (String) json.get("startTime"); String endTime = (String) json.get("endTime"); - String CPUThreshold = (String) json.get("CPUThreshold"); - String MemoryThreshold = (String) json.get("MemoryThreshold"); - String CPUPercentageThreshold = (String) json.get("CPUPercentageThreshold"); - String MemoryPercentageThreshold = (String) json.get("MemoryPercentageThreshold"); + String crossQueue = (String) json.get("crossQueue"); + String priorityCluster = (String) json.get("priorityCluster"); + String targetCPUThreshold = (String) json.get("targetCPUThreshold"); + String targetMemoryThreshold = (String) json.get("targetMemoryThreshold"); + String targetCPUPercentageThreshold = (String) json.get("targetCPUPercentageThreshold"); + String targetMemoryPercentageThreshold = (String) json.get("targetMemoryPercentageThreshold"); + String originCPUPercentageThreshold = (String) json.get("originCPUPercentageThreshold"); + String originMemoryPercentageThreshold = (String) json.get("originMemoryPercentageThreshold"); if (StringUtils.isBlank(clusterName) || StringUtils.isBlank(creator) || StringUtils.isBlank(username) || StringUtils.isBlank(isValid) || StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime) - || StringUtils.isBlank(CPUThreshold) - || StringUtils.isBlank(MemoryThreshold) - || StringUtils.isBlank(CPUPercentageThreshold) - || StringUtils.isBlank(MemoryPercentageThreshold)) { - return Message.error("Failed to add acrossClusterRule: Illegal Input Param"); + || StringUtils.isBlank(crossQueue) + || StringUtils.isBlank(priorityCluster) + || StringUtils.isBlank(targetCPUThreshold) + || StringUtils.isBlank(targetMemoryThreshold) + || StringUtils.isBlank(targetCPUPercentageThreshold) + || StringUtils.isBlank(targetMemoryPercentageThreshold) + || StringUtils.isBlank(originCPUPercentageThreshold) + || StringUtils.isBlank(originMemoryPercentageThreshold)) { + return Message.error("Failed to add acrossClusterRule, Illegal Input Param"); } try { @@ -309,10 +606,14 @@ public Message insertAcrossClusterRule( CommonUtils.ruleMap2String( startTime, endTime, - CPUThreshold, - MemoryThreshold, - CPUPercentageThreshold, - MemoryPercentageThreshold); + crossQueue, + priorityCluster, + targetCPUThreshold, + targetMemoryThreshold, + targetCPUPercentageThreshold, + targetMemoryPercentageThreshold, + originCPUPercentageThreshold, + originMemoryPercentageThreshold); AcrossClusterRule acrossClusterRule = new AcrossClusterRule(); acrossClusterRule.setClusterName(clusterName.toLowerCase()); acrossClusterRule.setCreator(creator); @@ -323,8 +624,8 @@ public Message insertAcrossClusterRule( acrossClusterRule.setIsValid(isValid); acrossClusterRuleService.insertAcrossClusterRule(acrossClusterRule); } catch (Exception e) { - log.info("add acrossClusterRule failed:" + e.getMessage()); - return Message.error("add acrossClusterRule failed:history already exist"); + log.info("add acrossClusterRule failed:", e); + return Message.error("add acrossClusterRule failed, rule already exits"); } return Message.ok(); diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/ConfigurationRestfulApi.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/ConfigurationRestfulApi.java index 11dfee8de1..5586455f6d 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/ConfigurationRestfulApi.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/ConfigurationRestfulApi.java @@ -142,7 +142,8 @@ public Message getFullTreesByAppName( ModuleUserUtils.getOperationUser( req, MessageFormat.format( - "ConfigurationException,engineType:{0},version:{1}", engineType, version)); + "getFullTreesByAppName,engineType:{0},version:{1},creator:{2}", + engineType, version, creator)); List labelList = LabelEntityParser.generateUserCreatorEngineTypeLabelList( username, creator, engineType, version); @@ -173,7 +174,7 @@ public Message getItemList( ModuleUserUtils.getOperationUser(req, "getItemList with engineType:" + engineType); // Adding * represents returning all configuration information if ("*".equals(engineType)) { - engineType = null; + engineType = ""; } List result = configKeyService.getConfigKeyList(engineType); List> filterResult = new ArrayList<>(); @@ -497,7 +498,8 @@ public Message getKeyValue( @ApiImplicitParam(name = "version", required = true, dataType = "String", value = "version"), @ApiImplicitParam(name = "creator", required = true, dataType = "String", value = "creator"), @ApiImplicitParam(name = "configKey", required = true, dataType = "String"), - @ApiImplicitParam(name = "configValue", required = true, dataType = "String") + @ApiImplicitParam(name = "configValue", required = true, dataType = "String"), + @ApiImplicitParam(name = "configKeyId", required = false, dataType = "String") }) @ApiOperationSupport(ignoreParameters = {"json"}) @RequestMapping(path = "/keyvalue", method = RequestMethod.POST) @@ -505,12 +507,13 @@ public Message saveKeyValue(HttpServletRequest req, @RequestBody Map json) throws ConfigurationException { String username = ModuleUserUtils.getOperationUser(req, "deleteKeyValue"); - String engineType = (String) json.getOrDefault("engineType", "*"); - String version = (String) json.getOrDefault("version", "*"); - String creator = (String) json.getOrDefault("creator", "*"); - String configKey = (String) json.get("configKey"); + String engineType = ((String) json.getOrDefault("engineType", "*")).trim(); + String version = ((String) json.getOrDefault("version", "*")).trim(); + String creator = ((String) json.getOrDefault("creator", "*")).trim(); + String configKey = ((String) json.get("configKey")).trim(); if (engineType.equals("*") && !version.equals("*")) { return Message.error("When engineType is any engine, the version must also be any version"); } @@ -690,10 +695,6 @@ public Message saveBaseKeyValue(HttpServletRequest req, @RequestBody ConfigKey c throws ConfigurationException, InstantiationException, IllegalAccessException { checkAdmin(ModuleUserUtils.getOperationUser(req, "saveBaseKeyValue")); String key = configKey.getKey(); - String name = configKey.getName(); - String treeName = configKey.getTreeName(); - String description = configKey.getDescription(); - Integer boundaryType = configKey.getBoundaryType(); String defaultValue = configKey.getDefaultValue(); String validateType = configKey.getValidateType(); String validateRange = configKey.getValidateRange(); @@ -701,13 +702,14 @@ public Message saveBaseKeyValue(HttpServletRequest req, @RequestBody ConfigKey c if (StringUtils.isBlank(key)) { return Message.error("key cannot be empty"); } - if (StringUtils.isBlank(name)) { + configKey.setKey(configKey.getKey().trim()); + if (StringUtils.isBlank(configKey.getName())) { return Message.error("name cannot be empty"); } - if (StringUtils.isBlank(description)) { + if (StringUtils.isBlank(configKey.getDescription())) { return Message.error("description cannot be empty"); } - if (StringUtils.isBlank(treeName)) { + if (StringUtils.isBlank(configKey.getTreeName())) { return Message.error("treeName cannot be empty"); } if (StringUtils.isBlank(validateType)) { @@ -716,7 +718,7 @@ public Message saveBaseKeyValue(HttpServletRequest req, @RequestBody ConfigKey c if (!validateType.equals("None") && StringUtils.isBlank(validateRange)) { return Message.error("validateRange cannot be empty"); } - if (null == boundaryType) { + if (null == configKey.getBoundaryType()) { return Message.error("boundaryType cannot be empty"); } if (StringUtils.isNotEmpty(defaultValue) @@ -730,6 +732,7 @@ public Message saveBaseKeyValue(HttpServletRequest req, @RequestBody ConfigKey c key, validateType, validateRange, defaultValue); throw new ConfigurationException(msg); } + configKey.setDefaultValue(configKey.getDefaultValue().trim()); if (null == configKey.getId()) { List configBykey = configKeyService.getConfigBykey(engineType, key, req.getHeader("Content-Language")); diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateManagerRestfulApi.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateRestfulApi.java similarity index 95% rename from linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateManagerRestfulApi.java rename to linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateRestfulApi.java index e0d52d423d..e6391c5278 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateManagerRestfulApi.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TemplateRestfulApi.java @@ -52,9 +52,9 @@ @Api(tags = "configuration template") @RestController @RequestMapping(path = "/configuration/template") -public class TemplateManagerRestfulApi { +public class TemplateRestfulApi { - private static final Logger logger = LoggerFactory.getLogger(TemplateManagerRestfulApi.class); + private static final Logger logger = LoggerFactory.getLogger(TemplateRestfulApi.class); @Autowired private TemplateConfigKeyService templateConfigKeyService; @@ -86,7 +86,8 @@ public Message updateKeyMapping(HttpServletRequest req, @RequestBody JsonNode js // check special admin token if (StringUtils.isNotBlank(token)) { if (!Configuration.isAdminToken(token)) { - return Message.error("Token has no permission to updateKeyMapping."); + logger.warn("Token:{} has no permission to updateKeyMapping.", token); + return Message.error("Token:" + token + " has no permission to updateKeyMapping."); } } else if (!Configuration.isAdmin(username)) { logger.warn("User:{} has no permission to updateKeyMapping.", username); @@ -159,7 +160,8 @@ public Message queryKeyInfoList(HttpServletRequest req, @RequestBody JsonNode js // check special admin token if (StringUtils.isNotBlank(token)) { if (!Configuration.isAdminToken(token)) { - return Message.error("Token has no permission to queryKeyInfoList."); + logger.warn("Token:{} has no permission to queryKeyInfoList.", token); + return Message.error("Token:" + token + " has no permission to queryKeyInfoList."); } } else if (!Configuration.isAdmin(username)) { logger.warn("User:{} has no permission to queryKeyInfoList.", username); @@ -210,7 +212,8 @@ public Message apply(HttpServletRequest req, @RequestBody JsonNode jsonNode) // check special admin token if (StringUtils.isNotBlank(token)) { if (!Configuration.isAdminToken(token)) { - return Message.error("Token has no permission to apply."); + logger.warn("Token:{} has no permission to apply.", token); + return Message.error("Token:" + token + " has no permission to apply."); } } else if (!Configuration.isAdmin(username)) { logger.warn("User:{} has no permission to apply.", username); diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TenantConfigrationRestfulApi.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TenantConfigrationRestfulApi.java index 3bd5b80834..4ab7455654 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TenantConfigrationRestfulApi.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/restful/api/TenantConfigrationRestfulApi.java @@ -18,6 +18,7 @@ package org.apache.linkis.configuration.restful.api; import org.apache.linkis.common.conf.Configuration; +import org.apache.linkis.configuration.entity.DepartmentTenantVo; import org.apache.linkis.configuration.entity.TenantVo; import org.apache.linkis.configuration.exception.ConfigurationException; import org.apache.linkis.configuration.service.TenantConfigService; @@ -75,15 +76,15 @@ public Message createTenant(HttpServletRequest req, @RequestBody TenantVo tenant if (!Configuration.isAdmin(userName)) { return Message.error("Failed to create-tenant,msg: only administrators can configure"); } + parameterVerification(tenantVo); if (tenantConfigService.isExist(tenantVo.getUser(), tenantVo.getCreator())) { throw new ConfigurationException("User-creator is existed"); } - parameterVerification(tenantVo); tenantConfigService.createTenant(tenantVo); } catch (DuplicateKeyException e) { return Message.error("Failed to create-tenant,msg:create user-creator is existed"); } catch (ConfigurationException e) { - return Message.error("Failed to update-tenant,msg:" + e.getMessage()); + return Message.error("Failed to create-tenant,msg:" + e.getMessage()); } return Message.ok(); } @@ -112,10 +113,6 @@ public Message updateTenant(HttpServletRequest req, @RequestBody TenantVo tenant if (!Configuration.isAdmin(userName)) { return Message.error("Failed to update-tenant,msg: only administrators can configure"); } - // if (!tenantConfigService.checkUserCteator(tenantVo.getUser(), tenantVo.getCreator(), - // null)) { - // throw new ConfigurationException("User-creator is not existed"); - // } parameterVerification(tenantVo); tenantConfigService.updateTenant(tenantVo); } catch (ConfigurationException e) { @@ -267,4 +264,127 @@ private void parameterVerification(TenantVo tenantVo) throws ConfigurationExcept throw new ConfigurationException("User && Creator cannot be both *"); } } + + @ApiImplicitParams({ + @ApiImplicitParam( + paramType = "body", + dataType = "DepartmentTenantVo", + name = "departmentTenantVo", + value = "departmentTenantVo") + }) + @ApiOperation( + value = "save-department-tenant", + notes = "save department tenant", + httpMethod = "POST", + response = Message.class) + @RequestMapping(path = "/save-department-tenant", method = RequestMethod.POST) + public Message saveDepartmentTenant( + HttpServletRequest req, @RequestBody DepartmentTenantVo departmentTenantVo) + throws ConfigurationException { + String userName = ModuleUserUtils.getOperationUser(req, "execute saveDepartmentTenant"); + if (!Configuration.isAdmin(userName)) { + return Message.error("Failed to save-department-tenant,msg: only administrator users to use"); + } + if (StringUtils.isBlank(departmentTenantVo.getTenantValue())) { + return Message.error("tenant can not be empty"); + } + if (StringUtils.isBlank(departmentTenantVo.getCreator())) { + return Message.error("creator can not be empty"); + } + if (StringUtils.isBlank(departmentTenantVo.getDepartmentId())) { + return Message.error("departmentId can not be empty"); + } + // Query whether the data exists before executing the update + if (StringUtils.isBlank(departmentTenantVo.getId())) { + DepartmentTenantVo departTenant = + tenantConfigService.queryDepartTenant( + departmentTenantVo.getCreator(), departmentTenantVo.getDepartmentId()); + if (null != departTenant) { + return Message.error("department creator is exist"); + } + } + tenantConfigService.saveDepartmentTenant(departmentTenantVo); + return Message.ok(); + } + + @ApiImplicitParams({ + @ApiImplicitParam( + paramType = "query", + dataType = "string", + name = "department", + value = "department"), + @ApiImplicitParam( + paramType = "query", + dataType = "string", + name = "creator", + value = "creator"), + @ApiImplicitParam( + paramType = "query", + dataType = "string", + name = "tenantValue", + value = "tenantValue"), + @ApiImplicitParam(paramType = "query", dataType = "int", name = "pageNow", value = "pageNow"), + @ApiImplicitParam(paramType = "query", dataType = "int", name = "pageSize", value = "pageSize") + }) + @ApiOperation( + value = "query-department-tenant", + notes = "query department tenant list", + httpMethod = "GET", + response = Message.class) + @RequestMapping(path = "/query-department-tenant", method = RequestMethod.GET) + public Message queryDepartmentTenant( + HttpServletRequest req, + @RequestParam(value = "departmentId", required = false) String departmentId, + @RequestParam(value = "creator", required = false) String creator, + @RequestParam(value = "tenantValue", required = false) String tenantValue, + @RequestParam(value = "pageNow", required = false, defaultValue = "1") Integer pageNow, + @RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize) { + String userName = ModuleUserUtils.getOperationUser(req, "execute queryDepartmentTenantList"); + if (!Configuration.isAdmin(userName)) { + return Message.error("Failed to query-tenant-list,msg: only administrator users to use"); + } + if (StringUtils.isBlank(departmentId)) departmentId = null; + if (StringUtils.isBlank(creator)) creator = null; + if (StringUtils.isBlank(tenantValue)) tenantValue = null; + Map resultMap = + tenantConfigService.queryDepartmentTenant( + departmentId, creator, tenantValue, pageNow, pageSize); + return Message.ok() + .data("tenantList", resultMap.get("tenantList")) + .data(JobRequestConstants.TOTAL_PAGE(), resultMap.get(JobRequestConstants.TOTAL_PAGE())); + } + + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "query", dataType = "int", name = "id", value = "id") + }) + @ApiOperation( + value = "delete-department-tenant", + notes = "delete department tenant", + httpMethod = "GET", + response = Message.class) + @RequestMapping(path = "/delete-department-tenant", method = RequestMethod.GET) + public Message deleteDepartmentTenant( + HttpServletRequest req, @RequestParam(value = "id") Integer id) { + String userName = + ModuleUserUtils.getOperationUser(req, "execute deleteDepartmentTenant,id: " + id); + if (!Configuration.isAdmin(userName)) { + return Message.error( + "Failed to delete-department-tenant,msg: only administrator users to use"); + } + if (StringUtils.isBlank(id.toString())) { + return Message.error("id can not be empty"); + } + tenantConfigService.deleteDepartmentTenant(id); + return Message.ok(); + } + + @ApiOperation( + value = "query department", + notes = "query department", + httpMethod = "GET", + response = Message.class) + @RequestMapping(path = "/query-department", method = RequestMethod.GET) + public Message queryDepartmentList() { + return Message.ok().data("departmentList", tenantConfigService.queryDepartmentList()); + } } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/AcrossClusterRuleService.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/AcrossClusterRuleService.java index 2fff11c871..c38b1a93a3 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/AcrossClusterRuleService.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/AcrossClusterRuleService.java @@ -18,20 +18,38 @@ package org.apache.linkis.configuration.service; import org.apache.linkis.configuration.entity.AcrossClusterRule; +import org.apache.linkis.governance.common.protocol.conf.AcrossClusterRequest; +import org.apache.linkis.governance.common.protocol.conf.AcrossClusterResponse; +import org.apache.linkis.rpc.Sender; +import java.util.List; import java.util.Map; public interface AcrossClusterRuleService { - void deleteAcrossClusterRule(String creator, String username) throws Exception; + void deleteAcrossClusterRule(Long id) throws Exception; + + void deleteAcrossClusterRuleByBatch(List ids) throws Exception; + + void deleteAcrossClusterRuleByUsername(String username) throws Exception; + + void deleteAcrossClusterRuleByCrossQueue(String crossQueue) throws Exception; void updateAcrossClusterRule(AcrossClusterRule acrossClusterRule) throws Exception; + void updateAcrossClusterRuleByBatch(List ids, AcrossClusterRule acrossClusterRule) + throws Exception; + void insertAcrossClusterRule(AcrossClusterRule acrossClusterRule) throws Exception; Map queryAcrossClusterRuleList( String creator, String username, String clusterName, Integer pageNow, Integer pageSize) throws Exception; - void validAcrossClusterRule(Long id, String isValid) throws Exception; + void validAcrossClusterRule(Long id, String isValid, String username) throws Exception; + + void validAcrossClusterRuleByBatch(List ids, String isValid) throws Exception; + + AcrossClusterResponse getAcrossClusterRuleByUsername( + AcrossClusterRequest acrossClusterRequest, Sender sender) throws Exception; } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/DepartmentService.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/DepartmentService.java new file mode 100644 index 0000000000..eb97f21dbb --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/DepartmentService.java @@ -0,0 +1,27 @@ +/* + * 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.configuration.service; + +import org.apache.linkis.governance.common.protocol.conf.DepartmentRequest; +import org.apache.linkis.governance.common.protocol.conf.DepartmentResponse; +import org.apache.linkis.rpc.Sender; + +public interface DepartmentService { + + DepartmentResponse getDepartmentByUser(DepartmentRequest departmentRequest, Sender sender); +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantConfigService.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantConfigService.java index 87b14a9c5e..0baa30c5f5 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantConfigService.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantConfigService.java @@ -17,9 +17,12 @@ package org.apache.linkis.configuration.service; +import org.apache.linkis.configuration.entity.DepartmentTenantVo; +import org.apache.linkis.configuration.entity.DepartmentVo; import org.apache.linkis.configuration.entity.TenantVo; import org.apache.linkis.configuration.exception.ConfigurationException; +import java.util.List; import java.util.Map; public interface TenantConfigService { @@ -36,4 +39,15 @@ Map queryTenantList( Boolean isExist(String user, String creator) throws ConfigurationException; TenantVo queryTenant(String user, String creator); + + void saveDepartmentTenant(DepartmentTenantVo departmentTenantVo) throws ConfigurationException; + + Map queryDepartmentTenant( + String departmentId, String creator, String tenantValue, Integer pageNow, Integer pageSize); + + void deleteDepartmentTenant(Integer id); + + DepartmentTenantVo queryDepartTenant(String creator, String departmentId); + + List queryDepartmentList(); } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantService.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantService.java index df88923455..f7a06ae49e 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantService.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/TenantService.java @@ -17,6 +17,8 @@ package org.apache.linkis.configuration.service; +import org.apache.linkis.governance.common.protocol.conf.DepartTenantRequest; +import org.apache.linkis.governance.common.protocol.conf.DepartTenantResponse; import org.apache.linkis.governance.common.protocol.conf.TenantRequest; import org.apache.linkis.governance.common.protocol.conf.TenantResponse; import org.apache.linkis.rpc.Sender; @@ -24,4 +26,6 @@ public interface TenantService { TenantResponse getTenantData(TenantRequest request, Sender sender); + + DepartTenantResponse getDepartTenantData(DepartTenantRequest departTenantRequest, Sender sender); } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/AcrossClusterRuleServiceImpl.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/AcrossClusterRuleServiceImpl.java index a906ca2d1a..487b0b57de 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/AcrossClusterRuleServiceImpl.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/AcrossClusterRuleServiceImpl.java @@ -21,6 +21,11 @@ import org.apache.linkis.configuration.entity.AcrossClusterRule; import org.apache.linkis.configuration.service.AcrossClusterRuleService; import org.apache.linkis.governance.common.constant.job.JobRequestConstants; +import org.apache.linkis.governance.common.protocol.conf.AcrossClusterRequest; +import org.apache.linkis.governance.common.protocol.conf.AcrossClusterResponse; +import org.apache.linkis.rpc.Sender; +import org.apache.linkis.rpc.message.annotation.Receiver; +import org.apache.linkis.server.BDPJettyServerHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,9 +34,13 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.linkis.configuration.conf.AcrossClusterRuleKeys.KEY_CROSS_QUEUE; +import static org.apache.linkis.configuration.conf.AcrossClusterRuleKeys.KEY_QUEUE_RULE; + @Service public class AcrossClusterRuleServiceImpl implements AcrossClusterRuleService { @@ -39,13 +48,33 @@ public class AcrossClusterRuleServiceImpl implements AcrossClusterRuleService { @Autowired private AcrossClusterRuleMapper ruleMapper; @Override - public void deleteAcrossClusterRule(String creator, String username) throws Exception { - ruleMapper.deleteAcrossClusterRule(creator, username); + public void deleteAcrossClusterRule(Long id) throws Exception { + AcrossClusterRule beforeRule = ruleMapper.getAcrossClusterRule(id, null); + if (beforeRule == null) { + throw new Exception("acrossClusterRule not exit"); + } + + ruleMapper.deleteAcrossClusterRule(id); + } + + @Override + public void deleteAcrossClusterRuleByBatch(List ids) throws Exception { + ruleMapper.deleteAcrossClusterRuleByBatch(ids); + } + + @Override + public void deleteAcrossClusterRuleByUsername(String username) throws Exception { + ruleMapper.deleteAcrossClusterRuleByUsername(username); + } + + @Override + public void deleteAcrossClusterRuleByCrossQueue(String crossQueue) throws Exception { + ruleMapper.deleteAcrossClusterRuleByCrossQueue(crossQueue); } @Override public void updateAcrossClusterRule(AcrossClusterRule newRule) throws Exception { - AcrossClusterRule beforeRule = ruleMapper.getAcrossClusterRule(newRule.getId()); + AcrossClusterRule beforeRule = ruleMapper.getAcrossClusterRule(newRule.getId(), null); if (beforeRule == null) { throw new Exception("acrossClusterRule not exit"); } @@ -58,6 +87,15 @@ public void updateAcrossClusterRule(AcrossClusterRule newRule) throws Exception ruleMapper.updateAcrossClusterRule(newRule); } + @Override + public void updateAcrossClusterRuleByBatch(List ids, AcrossClusterRule newRule) + throws Exception { + Date time = new Date(); + newRule.setUpdateTime(time); + + ruleMapper.updateAcrossClusterRuleByBatch(ids, newRule); + } + @Override public void insertAcrossClusterRule(AcrossClusterRule acrossClusterRule) throws Exception { Date time = new Date(); @@ -91,13 +129,45 @@ public Map queryAcrossClusterRuleList( } @Override - public void validAcrossClusterRule(Long id, String isValid) throws Exception { - AcrossClusterRule beforeRule = ruleMapper.getAcrossClusterRule(id); - + public void validAcrossClusterRule(Long id, String isValid, String username) throws Exception { + AcrossClusterRule beforeRule = ruleMapper.getAcrossClusterRule(id, username); if (beforeRule == null) { throw new Exception("acrossClusterRule not exit"); } - ruleMapper.validAcrossClusterRule(isValid, id); + ruleMapper.validAcrossClusterRule(isValid, id, username); + } + + @Override + public void validAcrossClusterRuleByBatch(List ids, String isValid) throws Exception { + ruleMapper.validAcrossClusterRuleByBatch(ids, isValid); + } + + @Receiver + @Override + public AcrossClusterResponse getAcrossClusterRuleByUsername( + AcrossClusterRequest acrossClusterRequest, Sender sender) throws Exception { + String username = acrossClusterRequest.username(); + AcrossClusterRule acrossClusterRule = ruleMapper.queryAcrossClusterRuleByUserName(username); + if (acrossClusterRule == null) { + return null; + } + String clusterName = acrossClusterRule.getClusterName(); + Map> rulesMap = new HashMap<>(); + try { + Gson gson = BDPJettyServerHelper.gson(); + rulesMap = gson.fromJson(acrossClusterRule.getRules(), rulesMap.getClass()); + Map queueRule = rulesMap.get(KEY_QUEUE_RULE); + String crossQueueName = queueRule.get(KEY_CROSS_QUEUE); + logger.info( + "{} configure across cluster name is {}, queue name is {}", + username, + acrossClusterRule.getClusterName(), + crossQueueName); + return new AcrossClusterResponse(clusterName, crossQueueName); + } catch (Exception e) { + logger.warn("Failed to parse rulesMap from rules"); + } + return null; } } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/DepartmentServiceImpl.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/DepartmentServiceImpl.java new file mode 100644 index 0000000000..45e607b5f0 --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/DepartmentServiceImpl.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.configuration.service.impl; + +import org.apache.linkis.configuration.dao.DepartmentMapper; +import org.apache.linkis.configuration.entity.DepartmentVo; +import org.apache.linkis.configuration.service.DepartmentService; +import org.apache.linkis.governance.common.protocol.conf.DepartmentRequest; +import org.apache.linkis.governance.common.protocol.conf.DepartmentResponse; +import org.apache.linkis.rpc.Sender; +import org.apache.linkis.rpc.message.annotation.Receiver; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Service +public class DepartmentServiceImpl implements DepartmentService { + + private static final Logger logger = LoggerFactory.getLogger(DepartmentServiceImpl.class); + + @Autowired private DepartmentMapper departmentMapper; + + @Receiver + @Override + public DepartmentResponse getDepartmentByUser( + DepartmentRequest departmentRequest, Sender sender) { + DepartmentVo departmentVo = departmentMapper.getDepartmentByUser(departmentRequest.user()); + if (null == departmentVo) { + logger.warn( + "Department data loading failed user {},department cache will set '' ", + departmentRequest.user()); + return new DepartmentResponse(departmentRequest.user(), "", ""); + } else { + return new DepartmentResponse( + departmentRequest.user(), departmentVo.getOrgId(), departmentVo.getOrgName()); + } + } +} diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantConfigServiceImpl.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantConfigServiceImpl.java index a5eb4c1098..07668b042c 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantConfigServiceImpl.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantConfigServiceImpl.java @@ -17,22 +17,28 @@ package org.apache.linkis.configuration.service.impl; +import org.apache.linkis.configuration.dao.DepartmentMapper; +import org.apache.linkis.configuration.dao.DepartmentTenantMapper; import org.apache.linkis.configuration.dao.UserTenantMapper; +import org.apache.linkis.configuration.entity.DepartmentTenantVo; +import org.apache.linkis.configuration.entity.DepartmentVo; import org.apache.linkis.configuration.entity.TenantVo; import org.apache.linkis.configuration.exception.ConfigurationException; import org.apache.linkis.configuration.service.TenantConfigService; -import org.apache.linkis.configuration.util.HttpsUtil; +import org.apache.linkis.configuration.util.ClientUtil; import org.apache.linkis.governance.common.constant.job.JobRequestConstants; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @@ -46,6 +52,10 @@ public class TenantConfigServiceImpl implements TenantConfigService { @Autowired private UserTenantMapper userTenantMapper; + @Autowired private DepartmentTenantMapper departmentTenantMapper; + + @Autowired private DepartmentMapper departmentMapper; + /** * * Querying the tenant configuration table * @@ -104,9 +114,9 @@ public void updateTenant(TenantVo tenantVo) throws ConfigurationException { throw new ConfigurationException("id can't be empty "); } dataProcessing(tenantVo); - TenantVo tenantVoLowerCase = toLowerCase(tenantVo); - logger.info("updateTenant : {}", tenantVoLowerCase); - userTenantMapper.updateTenant(tenantVoLowerCase); + tenantVo.setUpdateTime(new Date()); + logger.info("updateTenant : {}", tenantVo); + userTenantMapper.updateTenant(tenantVo); } /** @@ -117,23 +127,27 @@ public void updateTenant(TenantVo tenantVo) throws ConfigurationException { @Override public void createTenant(TenantVo tenantVo) throws ConfigurationException { dataProcessing(tenantVo); - TenantVo tenantVoLowerCase = toLowerCase(tenantVo); - tenantVoLowerCase.setCreateTime(new Date()); - logger.info("createTenant : {}", tenantVoLowerCase); + tenantVo.setCreateTime(new Date()); + tenantVo.setUpdateTime(new Date()); + logger.info("createTenant : {}", tenantVo); userTenantMapper.createTenant(tenantVo); } private void dataProcessing(TenantVo tenantVo) throws ConfigurationException { + // If tenant is set to invalid, skip ecm check + if (("N").equals(tenantVo.getIsValid())) { + return; + } AtomicReference tenantResult = new AtomicReference<>(false); // Obtain the tenant information of the ECM list - Map ecmListResult = null; + Map ecmList = null; try { - ecmListResult = HttpsUtil.sendHttp(null, null); - logger.info("Request ecm list response {}:", ecmListResult); + ecmList = ClientUtil.getEcmList(); + logger.info("Request ecm list response {}:", ecmList); } catch (IOException e) { - logger.warn("failed to get ecmResource data"); + logger.warn("failed to get ecmResource data", e); } - Map>> data = MapUtils.getMap(ecmListResult, "data"); + Map>> data = MapUtils.getMap(ecmList, "data"); List> emNodeVoList = data.get("EMs"); // Compare ECM list tenant labels for task emNodeVoList.forEach( @@ -143,8 +157,8 @@ private void dataProcessing(TenantVo tenantVo) throws ConfigurationException { .filter(labelmap -> labelmap.containsKey("tenant")) .forEach( map -> { - String tenant = map.get("tenant").toString().toLowerCase(); - if (tenant.equals(tenantVo.getTenantValue().toLowerCase())) { + String tenant = map.get("tenant").toString(); + if (tenant.equals(tenantVo.getTenantValue())) { tenantResult.set(true); } }); @@ -152,10 +166,10 @@ private void dataProcessing(TenantVo tenantVo) throws ConfigurationException { // Compare the value of ecm tenant if (!tenantResult.get()) throw new ConfigurationException("The ECM with the corresponding label was not found"); - if (!tenantVo.getCreator().equals("*")) { + if (!("*").equals(tenantVo.getCreator())) { // The beginning of tenantValue needs to contain creator - String creator = tenantVo.getCreator().toLowerCase(); - String[] tenantArray = tenantVo.getTenantValue().toLowerCase().split("_"); + String creator = tenantVo.getCreator(); + String[] tenantArray = tenantVo.getTenantValue().split("_"); if (tenantArray.length > 1 && !creator.equals(tenantArray[0])) { throw new ConfigurationException("tenantValue should contain creator first"); } @@ -165,8 +179,7 @@ private void dataProcessing(TenantVo tenantVo) throws ConfigurationException { @Override public Boolean isExist(String user, String creator) { boolean result = true; - Map resultMap = - queryTenantList(user.toLowerCase(), creator.toLowerCase(), null, 1, 20); + Map resultMap = queryTenantList(user, creator, null, 1, 20); Object tenantList = resultMap.getOrDefault(JobRequestConstants.TOTAL_PAGE(), 0); int total = Integer.parseInt(tenantList.toString()); if (total == 0) result = false; @@ -178,11 +191,66 @@ public TenantVo queryTenant(String user, String creator) { return userTenantMapper.queryTenant(user, creator); } - public TenantVo toLowerCase(TenantVo tenantVo) { - tenantVo.setTenantValue(tenantVo.getTenantValue().toLowerCase()); - tenantVo.setCreator(tenantVo.getCreator().toLowerCase()); - tenantVo.setUser(tenantVo.getUser().toLowerCase()); - tenantVo.setUpdateTime(new Date()); - return tenantVo; + @Override + public void saveDepartmentTenant(DepartmentTenantVo departmentTenantVo) + throws ConfigurationException { + TenantVo tenantVo = new TenantVo(); + BeanUtils.copyProperties(departmentTenantVo, tenantVo); + dataProcessing(tenantVo); + departmentTenantVo.setUpdateTime(new Date()); + if (StringUtils.isBlank(departmentTenantVo.getId())) { + departmentTenantVo.setCreateTime(new Date()); + departmentTenantMapper.insertTenant(departmentTenantVo); + } else { + departmentTenantMapper.updateTenant(departmentTenantVo); + } + } + + /** + * * + * + * @param departmentId + * @param creator + * @param tenantValue + * @param pageNow + * @param pageSize + * @return + */ + @Override + public Map queryDepartmentTenant( + String departmentId, String creator, String tenantValue, Integer pageNow, Integer pageSize) { + Map result = new HashMap<>(2); + List tenantVos = null; + PageHelper.startPage(pageNow, pageSize); + try { + tenantVos = departmentTenantMapper.queryTenantList(creator, departmentId, tenantValue); + } finally { + PageHelper.clearPage(); + } + PageInfo pageInfo = new PageInfo<>(tenantVos); + result.put("tenantList", tenantVos); + result.put(JobRequestConstants.TOTAL_PAGE(), pageInfo.getTotal()); + return result; + } + + public void deleteDepartmentTenant(Integer id) { + departmentTenantMapper.deleteTenant(id); + } + + @Override + public DepartmentTenantVo queryDepartTenant(String creator, String departmentId) { + return departmentTenantMapper.queryTenant(creator, departmentId); + } + + @Override + public List queryDepartmentList() { + return new ArrayList<>( + departmentMapper.queryDepartmentList().stream() + .collect( + Collectors.toMap( + DepartmentVo::getOrgId, + department -> department, + (existing, replacement) -> existing)) + .values()); } } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantServiceImpl.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantServiceImpl.java index 25d272c121..91523cc4a6 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantServiceImpl.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/service/impl/TenantServiceImpl.java @@ -17,9 +17,12 @@ package org.apache.linkis.configuration.service.impl; +import org.apache.linkis.configuration.entity.DepartmentTenantVo; import org.apache.linkis.configuration.entity.TenantVo; import org.apache.linkis.configuration.service.TenantConfigService; import org.apache.linkis.configuration.service.TenantService; +import org.apache.linkis.governance.common.protocol.conf.DepartTenantRequest; +import org.apache.linkis.governance.common.protocol.conf.DepartTenantResponse; import org.apache.linkis.governance.common.protocol.conf.TenantRequest; import org.apache.linkis.governance.common.protocol.conf.TenantResponse; import org.apache.linkis.rpc.Sender; @@ -45,10 +48,36 @@ public TenantResponse getTenantData(TenantRequest request, Sender sender) { if (null == tenantVo) { logger.warn( "TenantCache user {} creator {} data loading failed", request.user(), request.creator()); - return new TenantResponse(request.user(), request.creator(), ""); + return new TenantResponse(request.user(), request.creator(), "Y", ""); } else { return new TenantResponse( - tenantVo.getUser(), tenantVo.getCreator(), tenantVo.getTenantValue()); + tenantVo.getUser(), + tenantVo.getCreator(), + tenantVo.getIsValid(), + tenantVo.getTenantValue()); + } + } + + @Receiver + @Override + public DepartTenantResponse getDepartTenantData( + DepartTenantRequest departTenantRequest, Sender sender) { + DepartmentTenantVo departmentTenantVo = + tenantConfigService.queryDepartTenant( + departTenantRequest.creator(), departTenantRequest.departmentId()); + if (null == departmentTenantVo) { + logger.warn( + "DepartTenant data loading failed creator {} department {},departTenant cache will set '' ", + departTenantRequest.creator(), + departTenantRequest.departmentId()); + return new DepartTenantResponse( + departTenantRequest.creator(), departTenantRequest.departmentId(), "Y", ""); + } else { + return new DepartTenantResponse( + departmentTenantVo.getCreator(), + departmentTenantVo.getDepartmentId(), + departmentTenantVo.getIsValid(), + departmentTenantVo.getTenantValue()); } } } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/HttpsUtil.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/ClientUtil.java similarity index 93% rename from linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/HttpsUtil.java rename to linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/ClientUtil.java index 57fd7035da..56e0caa802 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/HttpsUtil.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/ClientUtil.java @@ -37,15 +37,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class HttpsUtil { +public class ClientUtil { - private static final Logger logger = LoggerFactory.getLogger(HttpsUtil.class); + private static final Logger logger = LoggerFactory.getLogger(ClientUtil.class); public static DWSClientConfig dwsClientConfig = createClientConfig(null, null); public static UJESClientImpl client = new UJESClientImpl(dwsClientConfig); - public static Map sendHttp(String url, Map properties) + public static Map getEcmList(String url, Map properties) throws IOException { if (null == dwsClientConfig) { dwsClientConfig = createClientConfig(url, properties); @@ -58,6 +58,10 @@ public static Map sendHttp(String url, Map prope return result.getResultMap(); } + public static Map getEcmList() throws IOException { + return getEcmList(null, null); + } + private static DWSClientConfig createClientConfig(String url, Map properties) { String realUrl = ""; if (StringUtils.isBlank(url)) { diff --git a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/CommonUtils.java b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/CommonUtils.java index 2d3f9b2008..d6898810fb 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/CommonUtils.java +++ b/linkis-public-enhancements/linkis-configuration/src/main/java/org/apache/linkis/configuration/util/CommonUtils.java @@ -42,28 +42,45 @@ public static boolean ipCheck(String str) { public static String ruleMap2String( String startTime, String endTime, - String CPUThreshold, - String MemoryThreshold, - String CPUPercentageThreshold, - String MemoryPercentageThreshold) + String crossQueue, + String priorityCluster, + String targetCPUThreshold, + String targetMemoryThreshold, + String targetCPUPercentageThreshold, + String targetMemoryPercentageThreshold, + String originCPUPercentageThreshold, + String originMemoryPercentageThreshold) throws JsonProcessingException { - Map queueRuleMap = new HashMap<>(); Map timeRuleMap = new HashMap<>(); - Map thresholdRuleMap = new HashMap<>(); + Map queueRuleMap = new HashMap<>(); + Map targetClusterRuleMap = new HashMap<>(); + Map originClusterRuleMap = new HashMap<>(); + Map priorityClusterRuleMap = new HashMap<>(); Map ruleMap = new HashMap<>(); - queueRuleMap.put(KEY_QUEUE_SUFFIX, KEY_ACROSS_CLUSTER_QUEUE_SUFFIX); timeRuleMap.put(KEY_START_TIME, startTime); timeRuleMap.put(KEY_END_TIME, endTime); - thresholdRuleMap.put(KEY_CPU_THRESHOLD, CPUThreshold); - thresholdRuleMap.put(KEY_MEMORY_THRESHOLD, MemoryThreshold); - thresholdRuleMap.put(KEY_CPU_PERCENTAGE_THRESHOLD, CPUPercentageThreshold); - thresholdRuleMap.put(KEY_MEMORY_PERCENTAGE_THRESHOLD, MemoryPercentageThreshold); - ruleMap.put(KEY_QUEUE_RULE, queueRuleMap); + queueRuleMap.put(KEY_CROSS_QUEUE, crossQueue); + targetClusterRuleMap.put(KEY_TARGET_CPU_THRESHOLD, targetCPUThreshold); + targetClusterRuleMap.put(KEY_TARGET_MEMORY_THRESHOLD, targetMemoryThreshold); + targetClusterRuleMap.put(KEY_TARGET_CPU_PERCENTAGE_THRESHOLD, targetCPUPercentageThreshold); + targetClusterRuleMap.put( + KEY_TARGET_MEMORY_PERCENTAGE_THRESHOLD, targetMemoryPercentageThreshold); + originClusterRuleMap.put(KEY_ORIGIN_CPU_PERCENTAGE_THRESHOLD, originCPUPercentageThreshold); + originClusterRuleMap.put( + KEY_ORIGIN_MEMORY_PERCENTAGE_THRESHOLD, originMemoryPercentageThreshold); + priorityClusterRuleMap.put(KEY_PRIORITY_CLUSTER, priorityCluster); ruleMap.put(KEY_TIME_RULE, timeRuleMap); - ruleMap.put(KEY_THRESHOLD_RULE, thresholdRuleMap); + ruleMap.put(KEY_QUEUE_RULE, queueRuleMap); + ruleMap.put(KEY_TARGET_CLUSTER_RULE, targetClusterRuleMap); + ruleMap.put(KEY_ORIGIN_CLUSTER_RULE, originClusterRuleMap); + ruleMap.put(KEY_PRIORITY_CLUSTER_RULE, priorityClusterRuleMap); ObjectMapper map2Json = BDPJettyServerHelper.jacksonJson(); String rules = map2Json.writeValueAsString(ruleMap); return rules; } + + public static String concatQueue(String crossQueue) { + return String.format("\"crossQueue\":\"%s\"", crossQueue); + } } diff --git a/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/common/DepartmentMapper.xml b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/common/DepartmentMapper.xml new file mode 100644 index 0000000000..9b7db1e830 --- /dev/null +++ b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/common/DepartmentMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + cluster_code,user_type,user_name,org_id,org_name,queue_name,db_name,interface_user,is_union_analyse,create_time,user_itsm_no + + + + + + \ No newline at end of file diff --git a/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/AcrossClusterRuleMapper.xml b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/AcrossClusterRuleMapper.xml index 2d6c1898a9..adb6c31337 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/AcrossClusterRuleMapper.xml +++ b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/AcrossClusterRuleMapper.xml @@ -47,14 +47,15 @@ acr.username, acr.create_time, acr.create_by, acr.update_time, acr.update_by, acr.rules FROM - `linkis_ps_configutation_lm_across_cluster_rule` acr + `linkis_ps_configuration_across_cluster_rule` acr WHERE id = #{id} + and username = #{username} + SELECT + acr.id, acr.cluster_name, acr.creator, + acr.username, acr.create_time, acr.create_by, + acr.update_time, acr.update_by, acr.rules + FROM + `linkis_ps_configuration_across_cluster_rule` acr + WHERE + username = #{username} limit 1 + \ No newline at end of file diff --git a/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/UserTenantMapper.xml b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/UserTenantMapper.xml index 5d8099f458..1494eae816 100644 --- a/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/UserTenantMapper.xml +++ b/linkis-public-enhancements/linkis-configuration/src/main/resources/mapper/mysql/UserTenantMapper.xml @@ -29,14 +29,15 @@ + - id,user,creator,tenant_value,create_time,update_time,`desc`,bussiness_user + id,user,creator,tenant_value,create_time,update_time,`desc`,bussiness_user,is_valid - `user`,creator,tenant_value,create_time,update_time,`desc`,bussiness_user + `user`,creator,tenant_value,create_time,update_time,`desc`,bussiness_user,is_valid @@ -47,7 +48,8 @@ #{createTime}, #{updateTime}, #{desc}, - #{bussinessUser} + #{bussinessUser}, + #{isValid} ) @@ -68,22 +70,23 @@ UPDATE linkis_cg_tenant_label_config - + user = #{user}, creator = #{creator}, tenant_value = #{tenantValue}, create_time = #{createTime}, update_time = #{updateTime}, `desc` = #{desc}, - bussiness_user = #{bussinessUser} - + bussiness_user = #{bussinessUser}, + is_valid = #{isValid} + WHERE id = #{id}