diff --git a/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/restful/ECMRestfulApi.java b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/restful/ECMRestfulApi.java new file mode 100644 index 0000000000..ff39c50400 --- /dev/null +++ b/linkis-computation-governance/linkis-engineconn-manager/linkis-engineconn-manager-server/src/main/java/org/apache/linkis/ecm/restful/ECMRestfulApi.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.linkis.ecm.restful; + +import org.apache.linkis.common.utils.JsonUtils; +import org.apache.linkis.ecm.server.exception.ECMErrorException; + +import org.apache.commons.io.IOUtils; +import org.apache.http.Consts; + +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import io.swagger.annotations.Api; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.linkis.ecm.errorcode.EngineconnServerErrorCodeSummary.LOG_IS_NOT_EXISTS; + +@Api(tags = "ECM") +@RequestMapping(path = "/engineconnManager") +@RestController +public class ECMRestfulApi { + + private final Logger logger = LoggerFactory.getLogger(ECMRestfulApi.class); + + @RequestMapping(path = "/downloadEngineLog", method = RequestMethod.POST) + public void downloadEngineLog( + HttpServletRequest req, HttpServletResponse response, @RequestBody JsonNode jsonNode) + throws IOException, ECMErrorException { + // String userName = ModuleUserUtils.getOperationUser(req, "openEngineLog"); + String emInstance = jsonNode.get("emInstance").asText(); + String instance = jsonNode.get("instance").asText(); + Map parameters = new HashMap<>(); + try { + parameters = + JsonUtils.jackson() + .readValue( + jsonNode.get("parameters").toString(), + new TypeReference>() {}); + } catch (JsonProcessingException e) { + logger.error( + "Fail to process the operation parameters: [{}] in request", + jsonNode.get("parameters").toString(), + e); + } + String logType = (String) parameters.get("logType"); + String logDirSuffix = (String) parameters.get("logDirSuffix"); + File inputFile = new File(logDirSuffix, logType); + if (!inputFile.exists()) { + throw new ECMErrorException( + LOG_IS_NOT_EXISTS.getErrorCode(), + MessageFormat.format(LOG_IS_NOT_EXISTS.getErrorDesc(), logDirSuffix)); + } else { + ServletOutputStream outputStream = null; + FileInputStream inputStream = null; + BufferedInputStream fis = null; + PrintWriter writer = null; + try { + inputStream = new FileInputStream(inputFile); + fis = new BufferedInputStream(inputStream); + byte[] buffer = new byte[1024]; + int bytesRead = 0; + response.reset(); + response.setCharacterEncoding(Consts.UTF_8.toString()); + java.nio.file.Path source = Paths.get(inputFile.getPath()); + response.addHeader("Content-Type", Files.probeContentType(source)); + response.addHeader( + "Content-Disposition", + "attachment;filename=" + instance.replace(":", "_") + "_" + logType + ".txt"); + outputStream = response.getOutputStream(); + while ((bytesRead = fis.read(buffer, 0, 1024)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + logger.error("download failed", e); + response.reset(); + response.setCharacterEncoding(Consts.UTF_8.toString()); + response.setContentType("text/plain; charset=utf-8"); + writer = response.getWriter(); + writer.append("error(错误):" + e.getMessage()); + writer.flush(); + } finally { + if (outputStream != null) { + outputStream.flush(); + } + IOUtils.closeQuietly(outputStream); + IOUtils.closeQuietly(fis); + IOUtils.closeQuietly(inputStream); + } + } + } +} diff --git a/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-core/src/main/scala/org/apache/linkis/gateway/config/GatewayConfiguration.scala b/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-core/src/main/scala/org/apache/linkis/gateway/config/GatewayConfiguration.scala index cace679033..c016b57094 100644 --- a/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-core/src/main/scala/org/apache/linkis/gateway/config/GatewayConfiguration.scala +++ b/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-core/src/main/scala/org/apache/linkis/gateway/config/GatewayConfiguration.scala @@ -110,4 +110,7 @@ object GatewayConfiguration { val LINKIS_CLUSTER_NAME = CommonVars("linkis.cluster.name", "") + val ENGINECONN_MANAGER_SPRING_NAME = + CommonVars("wds.linkis.engineconnmanager.name", "linkis-cg-engineconnmanager") + } diff --git a/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-server-support/src/main/scala/org/apache/linkis/gateway/ujes/parser/ECMRequestGatewayParser.scala b/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-server-support/src/main/scala/org/apache/linkis/gateway/ujes/parser/ECMRequestGatewayParser.scala new file mode 100644 index 0000000000..cdd9171889 --- /dev/null +++ b/linkis-spring-cloud-services/linkis-service-gateway/linkis-gateway-server-support/src/main/scala/org/apache/linkis/gateway/ujes/parser/ECMRequestGatewayParser.scala @@ -0,0 +1,83 @@ +/* + * 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.gateway.ujes.parser + +import org.apache.linkis.common.ServiceInstance +import org.apache.linkis.gateway.config.GatewayConfiguration +import org.apache.linkis.gateway.http.GatewayContext +import org.apache.linkis.gateway.parser.AbstractGatewayParser +import org.apache.linkis.gateway.springcloud.SpringCloudGatewayConfiguration.{ + normalPath, + API_URL_PREFIX +} +import org.apache.linkis.protocol.utils.ZuulEntranceUtils + +import org.springframework.stereotype.Component + +@Component +class ECMRequestGatewayParser extends AbstractGatewayParser { + override def shouldContainRequestBody(gatewayContext: GatewayContext): Boolean = false + + override def parse(gatewayContext: GatewayContext): Unit = { + logger.info("start begin ECMRequestGatewayParser {}", gatewayContext) + gatewayContext.getRequest.getRequestURI match { + case ECMRequestGatewayParser.ECM_EXECUTION_REGEX(version, execId) => + logger.info("----------------------1") + if (sendResponseWhenNotMatchVersion(gatewayContext, version)) return + logger.info("----------------------2") + val serviceInstance = + if ( + gatewayContext.getRequest.getQueryParams.containsKey(ECMRequestGatewayParser.INSTANCE) + ) { + logger.info("----------------------3") + val instances = + gatewayContext.getRequest.getQueryParams.get(ECMRequestGatewayParser.INSTANCE) + logger.info("----------------------{}", instances) + if (null != instances && instances.length == 1) { + logger.info("----------------------4") + ServiceInstance( + GatewayConfiguration.ENGINECONN_MANAGER_SPRING_NAME.getValue, + instances(0) + ) + } else { + logger.info("----------------------5") + ServiceInstance(GatewayConfiguration.ENGINECONN_MANAGER_SPRING_NAME.getValue, null) + } + } else { + logger.info("----------------------22") + ServiceInstance(GatewayConfiguration.ENGINECONN_MANAGER_SPRING_NAME.getValue, null) + } + logger.info("----------------------serviceInstance {}", serviceInstance) + gatewayContext.getGatewayRoute.setServiceInstance(serviceInstance) + case _ => + } + } + +} + +object ECMRequestGatewayParser { + + val ECM_HEADER = + normalPath(API_URL_PREFIX) + "rest_[a-zA-Z][a-zA-Z_0-9]*/(v\\d+)/engineconnManager/" + + val ECM_EXECUTION_REGEX = + (ECM_HEADER + "(downloadEngineLog)").r + + val INSTANCE = "instance" + +}