diff --git a/src/main/java/neatlogic/module/tenant/api/mailserver/MailServerTestApi.java b/src/main/java/neatlogic/module/tenant/api/mailserver/MailServerTestApi.java index 69154ee5b16c53d9d5a273ba41b1b5d2b56e5ad2..091a37b619aac3e17841098128eb530272d3fa27 100644 --- a/src/main/java/neatlogic/module/tenant/api/mailserver/MailServerTestApi.java +++ b/src/main/java/neatlogic/module/tenant/api/mailserver/MailServerTestApi.java @@ -25,6 +25,8 @@ import neatlogic.framework.restful.core.privateapi.PrivateApiComponentBase; import neatlogic.framework.util.EmailUtil; import org.springframework.stereotype.Service; +import java.util.Collections; + /** * 测试邮件服务器能否正常发送邮件 * @@ -58,10 +60,11 @@ public class MailServerTestApi extends PrivateApiComponentBase { @Description(desc = "nmtam.mailservertestapi.getname") @Override public Object myDoService(JSONObject jsonObj) throws Exception { - EmailUtil.sendEmailWithFile( + EmailUtil.sendHtmlEmail( "Test mail", "Your configured mail server information is available!", - jsonObj.getString("emailAddress") + Collections.singletonList(jsonObj.getString("emailAddress")), + null ); return null; } diff --git a/src/main/java/neatlogic/module/tenant/api/util/DownloadLocalFileApi.java b/src/main/java/neatlogic/module/tenant/api/util/DownloadLocalFileApi.java index d7f28ca9d43a4c598cc413de5bafa0a3427cb3bb..629f9f6859501c805386b36a71a3ab63e385f0df 100644 --- a/src/main/java/neatlogic/module/tenant/api/util/DownloadLocalFileApi.java +++ b/src/main/java/neatlogic/module/tenant/api/util/DownloadLocalFileApi.java @@ -37,14 +37,17 @@ import neatlogic.framework.restful.core.privateapi.PrivateBinaryStreamApiCompone import neatlogic.framework.util.HttpRequestUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.stereotype.Service; -import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.InputStream; +import java.util.LinkedHashMap; import java.util.Objects; @Service @@ -52,7 +55,7 @@ import java.util.Objects; @OperationType(type = OperationTypeEnum.SEARCH) public class DownloadLocalFileApi extends PrivateBinaryStreamApiComponentBase { - @Resource + @javax.annotation.Resource private ServerMapper serverMapper; @Override @@ -72,66 +75,112 @@ public class DownloadLocalFileApi extends PrivateBinaryStreamApiComponentBase { @Description(desc = "下载服务器文件") @Override public Object myDoService(JSONObject paramObj, HttpServletRequest request, HttpServletResponse response) throws Exception { + JSONObject resultObj = new JSONObject(new LinkedHashMap<>()); + boolean hasServerId = true; Integer serverId = paramObj.getInteger("serverId"); if (serverId == null) { + hasServerId = false; serverId = Config.SCHEDULE_SERVER_ID; } if (Objects.equals(serverId, Config.SCHEDULE_SERVER_ID)) { String fileName = null; String path = paramObj.getString("path"); - int index = path.lastIndexOf(File.separator); + int index = -1; + if (path.contains(File.separator)) { + index = path.lastIndexOf(File.separator); + } else { + index = path.lastIndexOf("/"); + } if (index != -1) { fileName = path.substring(index + 1); } else { fileName = path; } - fileName += "_serverId" + serverId; - File file = new File(path); - if (!file.exists()) { - throw new ApiRuntimeException("文件不存在"); - } - if (!file.isFile()) { - throw new ApiRuntimeException(path + "不是文件"); - } - if (!path.startsWith("file:")) { - path = "file:" + path; + InputStream in = null; + if (path.startsWith("jar:file:")) { + String locationPattern = null; + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + int index1 = path.lastIndexOf("jar!"); + if (index1 != -1) { + String classpath = path.substring(index1 + 4); + locationPattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + classpath; + } else { + locationPattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/" + fileName; + } + Resource[] resources = resolver.getResources(locationPattern); + for (Resource resource : resources) { + if (resource.exists()) { + if (Objects.equals(resource.getURL().toString(), path)) { + if (resource.isReadable()) { + in = resource.getInputStream(); + } else { + resultObj.put("message", "没有权限读取" + path + "文件"); + } + break; + } + } + } + if (in == null) { + resultObj.put("message", "文件不存在"); + } + } else { + File file = new File(path); + if (file.exists()) { + if (file.isFile()) { + if (file.canRead()) { + if (!path.startsWith("file:")) { + path = "file:" + path; + } + in = FileUtil.getData(path); + } else { + resultObj.put("message", "没有权限读取" + path + "文件"); + } + } else { + resultObj.put("message", path + "不是文件"); + } + } else { + resultObj.put("message", "文件不存在"); + } } - ServletOutputStream os; - InputStream in; - in = FileUtil.getData(path); if (in != null) { + if (!hasServerId) { + fileName += "_serverId" + serverId; + } response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", " attachment; filename=\"" + neatlogic.framework.util.FileUtil.getEncodedFileName(fileName) + "\""); - os = response.getOutputStream(); + ServletOutputStream os = response.getOutputStream(); IOUtils.copyLarge(in, os); os.flush(); os.close(); in.close(); } } else { - String host = null; TenantContext.get().setUseMasterDatabase(true); ServerClusterVo serverClusterVo = serverMapper.getServerByServerId(serverId); - if (serverClusterVo != null) { - host = serverClusterVo.getHost(); - } TenantContext.get().setUseMasterDatabase(false); - if (StringUtils.isNotBlank(host)) { - ServletOutputStream os = response.getOutputStream(); - String url = host + request.getRequestURI(); - HttpRequestUtil httpRequestUtil = HttpRequestUtil.download(url, "POST", os) - .setPayload(paramObj.toJSONString()) - .setAuthType(AuthenticateType.BUILDIN) - .setConnectTimeout(5000) - .setReadTimeout(5000) - .sendRequest(); - String error = httpRequestUtil.getError(); - if (StringUtils.isNotBlank(error)) { - throw new ApiRuntimeException(error); + if (serverClusterVo != null) { + String host = serverClusterVo.getHost(); + if (StringUtils.isNotBlank(host)) { + ServletOutputStream os = response.getOutputStream(); + String url = host + request.getRequestURI(); + HttpRequestUtil httpRequestUtil = HttpRequestUtil.download(url, "POST", os) + .setPayload(paramObj.toJSONString()) + .setAuthType(AuthenticateType.BUILDIN) + .setConnectTimeout(5000) + .setReadTimeout(5000) + .sendRequest(); + String error = httpRequestUtil.getError(); + if (StringUtils.isNotBlank(error)) { + throw new ApiRuntimeException(error); + } + } else { + resultObj.put("message", "serverId为" + serverId + "的应用服务器的`server_status`表中对应数据没有配置host"); } + } else { + resultObj.put("message", "找不到serverId为" + serverId + "的应用服务器"); } } - return null; + return resultObj; } @Override diff --git a/src/main/java/neatlogic/module/tenant/api/util/GetServerInfoApi.java b/src/main/java/neatlogic/module/tenant/api/util/GetServerInfoApi.java index 8fbb4ca1eae190fdd86d7f15cd176128fffef1c6..7145900a98126b011ff26488fb6904d3cbb4e21d 100644 --- a/src/main/java/neatlogic/module/tenant/api/util/GetServerInfoApi.java +++ b/src/main/java/neatlogic/module/tenant/api/util/GetServerInfoApi.java @@ -88,36 +88,41 @@ public class GetServerInfoApi extends PrivateApiComponentBase { JSONArray array = new JSONArray(); array.addAll(args); resultObj.put("命令行参数", array); + resultObj.put("Java虚拟机的系统属性", System.getProperties()); + resultObj.put("操作系统的环境变量", System.getenv()); resultObj.put("serverId", serverId); } else { - String host = null; TenantContext.get().setUseMasterDatabase(true); ServerClusterVo serverClusterVo = serverMapper.getServerByServerId(serverId); - if (serverClusterVo != null) { - host = serverClusterVo.getHost(); - } TenantContext.get().setUseMasterDatabase(false); - if (StringUtils.isNotBlank(host)) { - HttpServletRequest request = RequestContext.get().getRequest(); - String url = host + request.getRequestURI(); - HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) - .setPayload(paramObj.toJSONString()) - .setAuthType(AuthenticateType.BUILDIN) - .setConnectTimeout(5000) - .setReadTimeout(5000) - .sendRequest(); - String error = httpRequestUtil.getError(); - if (StringUtils.isNotBlank(error)) { - throw new ApiRuntimeException(error); - } - JSONObject resultJson = httpRequestUtil.getResultJson(); - if (MapUtils.isNotEmpty(resultJson)) { - String status = resultJson.getString("Status"); - if (!"OK".equals(status)) { - throw new RuntimeException(resultJson.getString("Message")); + if (serverClusterVo != null) { + String host = serverClusterVo.getHost(); + if (StringUtils.isNotBlank(host)) { + HttpServletRequest request = RequestContext.get().getRequest(); + String url = host + request.getRequestURI(); + HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) + .setPayload(paramObj.toJSONString()) + .setAuthType(AuthenticateType.BUILDIN) + .setConnectTimeout(5000) + .setReadTimeout(5000) + .sendRequest(); + String error = httpRequestUtil.getError(); + if (StringUtils.isNotBlank(error)) { + throw new ApiRuntimeException(error); + } + JSONObject resultJson = httpRequestUtil.getResultJson(); + if (MapUtils.isNotEmpty(resultJson)) { + String status = resultJson.getString("Status"); + if (!"OK".equals(status)) { + throw new RuntimeException(resultJson.getString("Message")); + } + resultObj = resultJson.getJSONObject("Return"); } - resultObj = resultJson.getJSONObject("Return"); + } else { + resultObj.put("message", "serverId为" + serverId + "的应用服务器的`server_status`表中对应数据没有配置host"); } + } else { + resultObj.put("message", "找不到serverId为" + serverId + "的应用服务器"); } } return resultObj; diff --git a/src/main/java/neatlogic/module/tenant/api/util/RefreshConfigApi.java b/src/main/java/neatlogic/module/tenant/api/util/RefreshConfigApi.java index d41b9aa05884bb0ebc788f6d744178f85e86d90d..7433b4bab4031329d20d8dea0c3bab15c9a679b9 100644 --- a/src/main/java/neatlogic/module/tenant/api/util/RefreshConfigApi.java +++ b/src/main/java/neatlogic/module/tenant/api/util/RefreshConfigApi.java @@ -82,34 +82,37 @@ public class RefreshConfigApi extends PrivateApiComponentBase { resultObj.put("config", prop); resultObj.put("serverId", serverId); } else { - String host = null; TenantContext.get().setUseMasterDatabase(true); ServerClusterVo serverClusterVo = serverMapper.getServerByServerId(serverId); - if (serverClusterVo != null) { - host = serverClusterVo.getHost(); - } TenantContext.get().setUseMasterDatabase(false); - if (StringUtils.isNotBlank(host)) { - HttpServletRequest request = RequestContext.get().getRequest(); - String url = host + request.getRequestURI(); - HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) - .setPayload(paramObj.toJSONString()) - .setAuthType(AuthenticateType.BUILDIN) - .setConnectTimeout(5000) - .setReadTimeout(5000) - .sendRequest(); - String error = httpRequestUtil.getError(); - if (StringUtils.isNotBlank(error)) { - throw new ApiRuntimeException(error); - } - JSONObject resultJson = httpRequestUtil.getResultJson(); - if (MapUtils.isNotEmpty(resultJson)) { - String status = resultJson.getString("Status"); - if (!"OK".equals(status)) { - throw new RuntimeException(resultJson.getString("Message")); + if (serverClusterVo != null) { + String host = serverClusterVo.getHost(); + if (StringUtils.isNotBlank(host)) { + HttpServletRequest request = RequestContext.get().getRequest(); + String url = host + request.getRequestURI(); + HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) + .setPayload(paramObj.toJSONString()) + .setAuthType(AuthenticateType.BUILDIN) + .setConnectTimeout(5000) + .setReadTimeout(5000) + .sendRequest(); + String error = httpRequestUtil.getError(); + if (StringUtils.isNotBlank(error)) { + throw new ApiRuntimeException(error); + } + JSONObject resultJson = httpRequestUtil.getResultJson(); + if (MapUtils.isNotEmpty(resultJson)) { + String status = resultJson.getString("Status"); + if (!"OK".equals(status)) { + throw new RuntimeException(resultJson.getString("Message")); + } + resultObj = resultJson.getJSONObject("Return"); } - resultObj = resultJson.getJSONObject("Return"); + } else { + resultObj.put("message", "serverId为" + serverId + "的应用服务器的`server_status`表中对应数据没有配置host"); } + } else { + resultObj.put("message", "找不到serverId为" + serverId + "的应用服务器"); } } return resultObj; diff --git a/src/main/java/neatlogic/module/tenant/api/util/SearchLocalFilePathApi.java b/src/main/java/neatlogic/module/tenant/api/util/SearchLocalFilePathApi.java new file mode 100644 index 0000000000000000000000000000000000000000..59d7fd56ceab4eee95be74148d0e0f3f1f5c2e62 --- /dev/null +++ b/src/main/java/neatlogic/module/tenant/api/util/SearchLocalFilePathApi.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package neatlogic.module.tenant.api.util; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import neatlogic.framework.asynchronization.threadlocal.RequestContext; +import neatlogic.framework.asynchronization.threadlocal.TenantContext; +import neatlogic.framework.auth.core.AuthAction; +import neatlogic.framework.auth.label.ADMIN; +import neatlogic.framework.common.config.Config; +import neatlogic.framework.common.constvalue.ApiParamType; +import neatlogic.framework.exception.core.ApiRuntimeException; +import neatlogic.framework.heartbeat.dao.mapper.ServerMapper; +import neatlogic.framework.heartbeat.dto.ServerClusterVo; +import neatlogic.framework.integration.authentication.enums.AuthenticateType; +import neatlogic.framework.restful.annotation.Description; +import neatlogic.framework.restful.annotation.Input; +import neatlogic.framework.restful.annotation.OperationType; +import neatlogic.framework.restful.annotation.Param; +import neatlogic.framework.restful.constvalue.OperationTypeEnum; +import neatlogic.framework.restful.core.privateapi.PrivateApiComponentBase; +import neatlogic.framework.util.HttpRequestUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Objects; + +@Service +@AuthAction(action = ADMIN.class) +@OperationType(type = OperationTypeEnum.OPERATE) +public class SearchLocalFilePathApi extends PrivateApiComponentBase { + + @Autowired + private ServerMapper serverMapper; + + @Override + public String getName() { + return "查询服务器文件路径"; + } + + @Input({ + @Param(name = "serverId", type = ApiParamType.INTEGER, desc = "服务器ID"), + @Param(name = "fileName", type = ApiParamType.STRING, isRequired = true, desc = "文件名"), + @Param(name = "scanPathList", type = ApiParamType.JSONARRAY, desc = "扫描路径列表", help = "默认只扫描类路径,如果需要扫描其他路径,就在这里添加,但不可以从\"/\"根目录开始扫描") + }) + @Description(desc = "查询服务器文件路径") + @Override + public Object myDoService(JSONObject paramObj) throws Exception { + JSONObject resultObj = new JSONObject(new LinkedHashMap<>()); + Integer serverId = paramObj.getInteger("serverId"); + if (serverId == null) { + serverId = Config.SCHEDULE_SERVER_ID; + } + if (Objects.equals(serverId, Config.SCHEDULE_SERVER_ID)) { + String fileName = paramObj.getString("fileName"); + JSONArray scanPathList = paramObj.getJSONArray("scanPathList"); + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + JSONArray resultList = new JSONArray(); + { + long startTime = System.currentTimeMillis(); + JSONObject jsonObj = new JSONObject(new LinkedHashMap<>()); + JSONArray filePathList = new JSONArray(); + JSONArray otherPathList = new JSONArray(); + String locationPattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/" + fileName; + Resource[] resources = resolver.getResources(locationPattern); + for (Resource resource : resources) { + if (resource.exists()) { + if (resource.isFile()) { + File file = resource.getFile(); + JSONObject pathObj = new JSONObject(); + pathObj.put("path", file.getPath()); + pathObj.put("canRead", file.canRead()); + pathObj.put("canWrite", file.canWrite()); + pathObj.put("isHidden", file.isHidden()); + pathObj.put("length", file.length()); + filePathList.add(pathObj); + } else { + JSONObject pathObj = new JSONObject(); + pathObj.put("path", resource.getURL().toString()); + pathObj.put("canRead", resource.isReadable()); + otherPathList.add(pathObj); + } + } + } + jsonObj.put("locationPattern", locationPattern); + jsonObj.put("timeCost", (System.currentTimeMillis() - startTime)); + jsonObj.put("filePathList", filePathList); + if (CollectionUtils.isNotEmpty(otherPathList)) { + jsonObj.put("otherPathList", otherPathList); + } + resultList.add(jsonObj); + } + { + if (CollectionUtils.isNotEmpty(scanPathList)) { + for (int i = 0; i < scanPathList.size(); i++) { + String scanPath = scanPathList.getString(i); + if (Objects.equals(scanPath, "/")) { + String locationPattern = "file:" + "/**/" + fileName; + JSONObject jsonObj = new JSONObject(new LinkedHashMap<>()); + jsonObj.put("locationPattern", locationPattern); + jsonObj.put("message", "不可以从根目录开始扫描"); + resultList.add(jsonObj); + } else { + long startTime = System.currentTimeMillis(); + JSONObject jsonObj = new JSONObject(new LinkedHashMap<>()); + JSONArray filePathList = new JSONArray(); + JSONArray otherPathList = new JSONArray(); + String locationPattern = "file:" + scanPath + "/**/" + fileName; + Resource[] resources = resolver.getResources(locationPattern); + for (Resource resource : resources) { + if (resource.exists()) { + if (resource.isFile()) { + File file = resource.getFile(); + JSONObject pathObj = new JSONObject(); + pathObj.put("path", file.getPath()); + pathObj.put("canRead", file.canRead()); + pathObj.put("canWrite", file.canWrite()); + pathObj.put("isHidden", file.isHidden()); + pathObj.put("length", file.length()); + filePathList.add(pathObj); + } else { + JSONObject pathObj = new JSONObject(); + pathObj.put("path", resource.getURL().toString()); + pathObj.put("canRead", resource.isReadable()); + otherPathList.add(pathObj); + } + } + } + jsonObj.put("locationPattern", locationPattern); + jsonObj.put("timeCost", (System.currentTimeMillis() - startTime)); + jsonObj.put("filePathList", filePathList); + if (CollectionUtils.isNotEmpty(otherPathList)) { + jsonObj.put("otherPathList", otherPathList); + } + resultList.add(jsonObj); + } + } + } + } + resultObj.put("tbodyList", resultList); + resultObj.put("serverId", serverId); + } else { + TenantContext.get().setUseMasterDatabase(true); + ServerClusterVo serverClusterVo = serverMapper.getServerByServerId(serverId); + TenantContext.get().setUseMasterDatabase(false); + if (serverClusterVo != null) { + String host = serverClusterVo.getHost(); + if (StringUtils.isNotBlank(host)) { + HttpServletRequest request = RequestContext.get().getRequest(); + String url = host + request.getRequestURI(); + HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) + .setPayload(paramObj.toJSONString()) + .setAuthType(AuthenticateType.BUILDIN) + .setConnectTimeout(5000) + .setReadTimeout(5000) + .sendRequest(); + String error = httpRequestUtil.getError(); + if (StringUtils.isNotBlank(error)) { + throw new ApiRuntimeException(error); + } + JSONObject resultJson = httpRequestUtil.getResultJson(); + if (MapUtils.isNotEmpty(resultJson)) { + String status = resultJson.getString("Status"); + if (!"OK".equals(status)) { + throw new RuntimeException(resultJson.getString("Message")); + } + resultObj = resultJson.getJSONObject("Return"); + } + } else { + resultObj.put("message", "serverId为" + serverId + "的应用服务器的`server_status`表中对应数据没有配置host"); + } + } else { + resultObj.put("message", "找不到serverId为" + serverId + "的应用服务器"); + } + } + return resultObj; + } + + @Override + public String getToken() { + return "util/localfile/path/search"; + } +} diff --git a/src/main/java/neatlogic/module/tenant/api/util/UpdateLocalFileApi.java b/src/main/java/neatlogic/module/tenant/api/util/UpdateLocalFileApi.java new file mode 100644 index 0000000000000000000000000000000000000000..db7c72d42d41934ef0de7246efb6d5c0d41761bf --- /dev/null +++ b/src/main/java/neatlogic/module/tenant/api/util/UpdateLocalFileApi.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2025 深圳极向量科技有限公司 All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package neatlogic.module.tenant.api.util; + +import com.alibaba.fastjson.JSONObject; +import neatlogic.framework.asynchronization.threadlocal.RequestContext; +import neatlogic.framework.asynchronization.threadlocal.TenantContext; +import neatlogic.framework.auth.core.AuthAction; +import neatlogic.framework.auth.label.ADMIN; +import neatlogic.framework.common.config.Config; +import neatlogic.framework.common.constvalue.ApiParamType; +import neatlogic.framework.exception.core.ApiRuntimeException; +import neatlogic.framework.exception.file.FileStorageMediumHandlerNotFoundException; +import neatlogic.framework.file.core.FileStorageMediumFactory; +import neatlogic.framework.file.core.IFileStorageHandler; +import neatlogic.framework.file.dao.mapper.FileMapper; +import neatlogic.framework.file.dto.FileVo; +import neatlogic.framework.heartbeat.dao.mapper.ServerMapper; +import neatlogic.framework.heartbeat.dto.ServerClusterVo; +import neatlogic.framework.integration.authentication.enums.AuthenticateType; +import neatlogic.framework.restful.annotation.Description; +import neatlogic.framework.restful.annotation.Input; +import neatlogic.framework.restful.annotation.OperationType; +import neatlogic.framework.restful.annotation.Param; +import neatlogic.framework.restful.constvalue.OperationTypeEnum; +import neatlogic.framework.restful.core.privateapi.PrivateApiComponentBase; +import neatlogic.framework.util.HttpRequestUtil; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.LinkedHashMap; +import java.util.Objects; + +@Service +@AuthAction(action = ADMIN.class) +@OperationType(type = OperationTypeEnum.OPERATE) +public class UpdateLocalFileApi extends PrivateApiComponentBase { + + @Resource + private ServerMapper serverMapper; + + @Resource + private FileMapper fileMapper; + + @Override + public String getName() { + return "更新服务器文件"; + } + + @Input({ + @Param(name = "serverId", type = ApiParamType.INTEGER, desc = "服务器ID"), + @Param(name = "fileId", type = ApiParamType.LONG, isRequired = true, desc = "附件ID"), + @Param(name = "path", type = ApiParamType.STRING, isRequired = true, desc = "需要更新的文件路径") + }) + @Description(desc = "更新服务器文件") + @Override + public Object myDoService(JSONObject paramObj) throws Exception { + JSONObject resultObj = new JSONObject(new LinkedHashMap<>()); + Integer serverId = paramObj.getInteger("serverId"); + if (serverId == null) { + serverId = Config.SCHEDULE_SERVER_ID; + } + if (Objects.equals(serverId, Config.SCHEDULE_SERVER_ID)) { + Long fileId = paramObj.getLong("fileId"); + String path = paramObj.getString("path"); + FileVo fileVo = fileMapper.getFileById(fileId); + String filePath = fileVo.getPath(); + String[] split = filePath.split(":", 2); + IFileStorageHandler handler = FileStorageMediumFactory.getHandler(split[0].toUpperCase()); + if (handler == null) { + throw new FileStorageMediumHandlerNotFoundException(split[0]); + } + try (InputStream inputStream = handler.getData(filePath)) { + Path targetPath = Paths.get(path); + File file = targetPath.toFile(); + resultObj.put("path", file.getPath()); + if (file.exists()) { + resultObj.put("文件是否已存在", "是"); + long length = Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING); + resultObj.put("操作类型", "覆盖"); + resultObj.put("文件大小", length); + } else { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + resultObj.put("文件是否已存在", "否"); + long length = Files.copy(inputStream, targetPath); + resultObj.put("操作类型", "新增"); + resultObj.put("文件大小", length); + } + } + resultObj.put("serverId", serverId); + } else { + TenantContext.get().setUseMasterDatabase(true); + ServerClusterVo serverClusterVo = serverMapper.getServerByServerId(serverId); + TenantContext.get().setUseMasterDatabase(false); + if (serverClusterVo != null) { + String host = serverClusterVo.getHost(); + if (StringUtils.isNotBlank(host)) { + HttpServletRequest request = RequestContext.get().getRequest(); + String url = host + request.getRequestURI(); + HttpRequestUtil httpRequestUtil = HttpRequestUtil.post(url) + .setPayload(paramObj.toJSONString()) + .setAuthType(AuthenticateType.BUILDIN) + .setConnectTimeout(5000) + .setReadTimeout(5000) + .sendRequest(); + String error = httpRequestUtil.getError(); + if (StringUtils.isNotBlank(error)) { + throw new ApiRuntimeException(error); + } + JSONObject resultJson = httpRequestUtil.getResultJson(); + if (MapUtils.isNotEmpty(resultJson)) { + String status = resultJson.getString("Status"); + if (!"OK".equals(status)) { + throw new RuntimeException(resultJson.getString("Message")); + } + resultObj = resultJson.getJSONObject("Return"); + } + } else { + resultObj.put("message", "serverId为" + serverId + "的应用服务器的`server_status`表中对应数据没有配置host"); + } + } else { + resultObj.put("message", "找不到serverId为" + serverId + "的应用服务器"); + } + } + return resultObj; + } + + @Override + public String getToken() { + return "util/localfile/update"; + } + + @Override + public int needAudit() { + return 1; + } + +}