From 41021633bfee5b5c9c57cb888423f3392c530f98 Mon Sep 17 00:00:00 2001
From: ludc
Date: 星期一, 25 三月 2024 18:31:08 +0800
Subject: [PATCH] 业务类型bug修改,集成接口,远程部署等功能修改。

---
 Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/service/impl/DeployAppsServiceImpl.java |  371 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 361 insertions(+), 10 deletions(-)

diff --git a/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/service/impl/DeployAppsServiceImpl.java b/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/service/impl/DeployAppsServiceImpl.java
index 6913f3f..2427ebe 100644
--- a/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/service/impl/DeployAppsServiceImpl.java
+++ b/Source/UBCS/ubcs-service/ubcs-deploy/src/main/java/com/vci/ubcs/deploy/service/impl/DeployAppsServiceImpl.java
@@ -5,45 +5,107 @@
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.nacos.shaded.com.google.protobuf.ServiceException;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.vci.ubcs.deploy.entity.CmdConfig;
 import com.vci.ubcs.deploy.entity.DeployApps;
-import com.vci.ubcs.deploy.entity.Instance;
+import com.vci.ubcs.deploy.enumpack.CmdConfigEnum;
 import com.vci.ubcs.deploy.mapper.DeployAppsMapper;
 import com.vci.ubcs.deploy.service.IDeployAppsService;
 import com.vci.ubcs.deploy.vo.DeployAppsVO;
 import com.vci.ubcs.starter.util.HttpUtils;
+import jodd.io.StreamGobbler;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.UrlUtil;
+import org.springblade.core.tool.utils.WebUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.client.ServiceInstance;
 import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
 import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.net.InetAddress;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 /**
  * @author ludc
  * @date 2024/1/7 19:54
  */
 @Service
-public class DeployAppsServiceImpl extends ServiceImpl<DeployAppsMapper, DeployApps> implements IDeployAppsService {
+@RequiredArgsConstructor
+@Slf4j
+public class DeployAppsServiceImpl extends ServiceImpl<DeployAppsMapper, DeployApps> implements IDeployAppsService, EnvironmentAware {
 
-	@Autowired
-	private DeployAppsMapper deployAppsMapper;
+	private final DeployAppsMapper deployAppsMapper;
 
 	@Value("${password-free.pwd-free-addr:localhost}")
 	private String pwdFreeAddr;
 
-	// 閫氳繃鏈嶅姟娉ㄥ唽涓績鑾峰彇缃戝叧鐨勭鍙e彿
+	/**
+	 * 閫氳繃鏈嶅姟娉ㄥ唽涓績鑾峰彇缃戝叧鐨勭鍙e彿
+	 */
 	@Autowired
 	private DiscoveryClient discoveryClient;
+
+	/**
+	 * 鍚勪釜鏈嶅姟瀛樻斁鐨勭殑鐖惰矾寰�
+	 */
+	@Value("${local-log.parent-path:/data1/ubcs/ubcs-server}")
+	private String PARENTPATH;
+
+	/**
+	 * 鏃ュ織鏂囦欢鐨勫叿浣撲綅缃�
+	 */
+	@Value("${local-log.log-path:/target/log}")
+	private String LOGPATH;
+
+	/**
+	 * 鏍规嵁鎿嶄綔绯荤粺鐢熸垚鍒嗛殧绗�
+	 */
+	private String SEPARATOR = "/";
+
+	/**
+	 * 鏍规嵁褰撳墠杩愯鐨勭幆澧冿紝瀵归厤缃殑鏃ュ織璺緞鏍煎紡杩涜璋冩暣
+	 * @param environment
+	 */
+	@Override
+	public void setEnvironment(Environment environment) {
+		String os = environment.getProperty("os.name").toLowerCase();
+		if (!os.contains("win")) {
+			this.SEPARATOR = "/";
+		}else{
+			this.SEPARATOR = "\\";
+		}
+	}
 
 	@Override
 	public List<DeployAppsVO> getApplications(ServletRequest servletRequest) throws ServiceException {
@@ -80,12 +142,284 @@
 					deployAppsVO.setStatusTimestamp(jsonObject.get("statusTimestamp").toString());
 					deployAppsVOList.add(deployAppsVO);
 				}
-
 			}
 		}catch (Exception e){
 			throw new ServiceException("璋冪敤ubcs-admin鑾峰彇鏈嶅姟淇℃伅澶辫触锛屽師鍥狅細"+e.getMessage());
 		}
+		// 鍐嶆煡璇㈠簱涓凡缁忓瓨鍦ㄧ殑鏈嶅姟閰嶇疆淇℃伅锛岃繘琛屾槸鍚﹀凡缁忓惎鍔ㄧ殑鍒ゆ柇
+		List<DeployApps> deployApps = deployAppsMapper.selectList(null);
+		// 搴撲腑鏈厤缃紝鐩存帴杩斿洖姝e湪杩愯鐨勬湇鍔′俊鎭�
+		if(deployApps.isEmpty()){
+			return deployAppsVOList;
+		}
+		// 绛涢�夊嚭涓嶅湪杩愯鐨勫苟鐢熸垚榛樿鐨勬湇鍔′俊鎭�
+		List<DeployAppsVO> deployAppsVOS1 = deployApps.stream()
+			.filter(deployApp -> deployAppsVOList.stream()
+				.noneMatch(deployAppVO -> deployApp.getServerName().equals(deployAppVO.getName()) &&
+					deployApp.getServerName().equals(deployAppVO.getName())))
+			.map(deployApp -> {
+				DeployAppsVO deployAppsVO2 = new DeployAppsVO(deployApp.getServerName(), "DOWN", "", "", 0);
+				if(deployApp.getServerName().equals("web")){
+					deployAppsVO2.setStatus("UP");
+					deployAppsVO2.setPort("8080");
+					deployAppsVO2.setServiceNum(1);
+				}
+				return deployAppsVO2;
+			})
+			.collect(Collectors.toList());
+		deployAppsVOList.addAll(deployAppsVOS1);
 		return deployAppsVOList;
+	}
+
+	@Override
+	public DeployApps saveOrGetServiceConfInfo(DeployAppsVO deployAppsVO) throws ServiceException {
+		if(deployAppsVO.getName().isEmpty()){
+			throw new ServiceException("缂哄皯蹇呬紶鍙傛暟name");
+		}
+		List<DeployApps> deployApps = deployAppsMapper.selectList(Wrappers.<DeployApps>query().lambda().eq(DeployApps::getServerName, deployAppsVO.getName()));
+		if(Func.isNotEmpty(deployApps)){
+			return deployApps.get(0);
+		}
+		// 鏈粠搴撲腑鏌ヨ鍒帮紝闇�瑕佺敓鎴愭湇鍔′俊鎭繚瀛橀粯璁や俊鎭埌搴撲腑
+		DeployApps defaultDeployApps = new DeployApps();
+		defaultDeployApps.setLogPath(PARENTPATH + SEPARATOR + deployAppsVO.getName().replace("-","_") + LOGPATH);
+		defaultDeployApps.setServerName(deployAppsVO.getName());
+		defaultDeployApps.setStartCmd(CmdConfigEnum.START_CMD.getValue() + deployAppsVO.getName());
+		defaultDeployApps.setStopCmd(CmdConfigEnum.STOP_CMD.getValue() + deployAppsVO.getName());
+		defaultDeployApps.setRestartCmd(CmdConfigEnum.RESTART_CMD.getValue() + deployAppsVO.getName());
+		defaultDeployApps.setServerPath(PARENTPATH + SEPARATOR + deployAppsVO.getName().replace("-","_"));
+		int eft = deployAppsMapper.insert(defaultDeployApps);
+		if (!SqlHelper.retBool(eft)) {
+			throw new ServiceException("鐢熸垚榛樿鏈嶅姟淇℃伅鍒板簱涓椂澶辫触锛�");
+		}
+		return defaultDeployApps;
+	}
+
+	/**
+	 * 淇敼鎴栦繚瀛�
+	 * @param deployAppsVO
+	 * @return
+	 * @throws ServiceException
+	 */
+	@Override
+	public R saveOrUpdateServiceInfo(DeployAppsVO deployAppsVO) throws ServiceException {
+		boolean checkBoolean = checkCmdVer(deployAppsVO.getStartCmd()) && checkCmdVer(deployAppsVO.getStopCmd()) && checkCmdVer(deployAppsVO.getRestartCmd());
+		if(checkBoolean){
+			return R.fail("閰嶇疆鐨勫懡浠や腑鍖呭惈鍗遍櫓鍛戒护锛屽锛歳m銆乵v銆乺m -rf銆乧hmod绛夊懡浠ゅ拰鍏抽敭璇嶏紒 ");
+		}
+		return R.status(this.saveOrUpdate(deployAppsVO));
+	}
+
+	/**
+	 * 鏂板鏈嶅姟淇℃伅
+	 * @param deployApps
+	 * @return
+	 * @throws ServiceException
+	 */
+	@Override
+	public boolean addSave(DeployApps deployApps) throws ServiceException {
+		if (Func.isBlank(deployApps.getServerName()) || Func.isBlank(deployApps.getServerPath())) {
+			throw new ServiceException("蹇呬紶鍙傛暟[鏈嶅姟鍚嶇О锛屾湇鍔″瓨鏀捐矾寰刔涓嶈兘涓虹┖");
+		}
+		List<DeployApps> deployAppsList = deployAppsMapper.selectList(Wrappers.<DeployApps>query().lambda().eq(DeployApps::getServerName, deployApps.getServerName()));
+		if (!deployAppsList.isEmpty()) {
+			throw new ServiceException("鏂板鏈嶅姟鐨勬湇鍔″悕閲嶅锛�");
+		}
+		return SqlHelper.retBool(deployAppsMapper.insert(deployApps));
+	}
+
+	/**
+	 * 鏇存柊鏂囦欢涓婁紶
+	 * @param files
+	 * @param serverName
+	 * @return
+	 */
+	@Override
+	public R importJarUpdate(MultipartFile[] files, String serverName) throws ServiceException {
+		// 鏍规嵁鏈嶅姟鍚嶆煡鐪嬪埌鏈嶅姟鐩稿叧淇℃伅
+		List<DeployApps> deployAppsDB = deployAppsMapper.selectList(Wrappers.<DeployApps>query().lambda().eq(DeployApps::getServerName, serverName));
+		if(deployAppsDB.isEmpty()){
+			return R.fail("No configuration information related to "+ serverName +" service found");
+		}
+		// 閬嶅巻MultipartFile鏁扮粍锛岄�愪釜澶勭悊鏂囦欢
+		try {
+			for (MultipartFile file : files) {
+				// 閰嶇疆浜嗗浠芥枃浠惰矾寰勶紝鍏堝浠藉啀鏇挎崲
+				if(Func.isNotEmpty(deployAppsDB.get(0).getFileBack())){
+					File backFile = new File(deployAppsDB.get(0).getFileBack());
+					// 璺緞涓嶅瓨鍦ㄥ氨鍒涘缓
+					if (!backFile.exists()) {
+						backFile.mkdirs();
+					}
+					String backName = "";
+					String fileType = "file";
+					// 鏄帇缂╂枃浠�,鍥犱负鍙細瀛樺湪涓ょ鎯呭喌锛屾枃浠跺悕鏄帇缂╂枃浠讹紝鎴栬�呮枃浠讹紙.jar绫诲瀷鐨勬枃浠讹級
+					// 褰撳墠鏃堕棿
+					String currentDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+					if (file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) {
+						backName = file.getOriginalFilename().replace(".zip","_" + currentDateTime);
+					}else{
+						backName = file.getOriginalFilename().replace(".","_" + currentDateTime + ".");
+					}
+					File source = new File(deployAppsDB.get(0).getServerPath() + this.SEPARATOR + file.getOriginalFilename().replace(".zip", ""));
+					File destination = new File(deployAppsDB.get(0).getFileBack() + this.SEPARATOR + backName);
+					copyFolder(source, destination);
+				}
+				Path filePath = Paths.get(deployAppsDB.get(0).getServerPath(), file.getOriginalFilename());
+				Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
+				// 妫�鏌ユ枃浠剁被鍨嬶紝濡傛灉鏄帇缂╂枃浠跺垯瑙e帇缂�
+				if (file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) {
+					//sourcePath鍘嬬缉鍖呮枃浠惰矾寰�
+					try (ZipFile zipFile = new ZipFile(new File(deployAppsDB.get(0).getServerPath()+ this.SEPARATOR +file.getOriginalFilename()))) {
+						Enumeration enumeration = zipFile.entries();
+						while (enumeration.hasMoreElements()) {
+							//渚濇鑾峰彇鍘嬬缉鍖呭唴鐨勬枃浠跺疄浣撳璞�
+							ZipEntry entry = (ZipEntry) enumeration.nextElement();
+							String name = entry.getName();
+							if (entry.isDirectory()) {
+								continue;
+							}
+							try (BufferedInputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry))) {
+								// 闇�瑕佸垽鏂枃浠舵墍鍦ㄧ殑鐩綍鏄惁瀛樺湪锛屽鐞嗗帇缂╁寘閲岄潰鏈夋枃浠跺す鐨勬儏鍐�
+								String outName = deployAppsDB.get(0).getServerPath() + this.SEPARATOR + name;
+								File outFile = new File(outName);
+								File tempFile = new File(outName.substring(0, outName.lastIndexOf("/")));
+								if (!tempFile.exists()) {
+									tempFile.mkdirs();
+								}
+								try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFile))) {
+									int len;
+									byte[] buffer = new byte[1024];
+									while ((len = inputStream.read(buffer)) > 0) {
+										outputStream.write(buffer, 0, len);
+									}
+								}
+							}
+						}
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+					File file1 = new File(deployAppsDB.get(0).getServerPath() + SEPARATOR + file.getOriginalFilename());
+					// 鍘嬬缉鏂囦欢涓婁紶鎴愬姛涔嬪悗锛屽垹闄よВ鍘嬫枃浠�
+					file1.delete();
+				}
+			}
+			String output = execute(deployAppsDB.get(0),"UP");
+			return R.success(output.toString());
+		} catch (IOException e) {
+			e.printStackTrace();
+			log.error(e.getMessage());
+			return R.fail("Failed to upload files");
+		}
+
+	}
+
+	/**
+	 * 鎵ц鍛戒护
+	 * @param deployAppsVO
+	 * @return
+	 */
+	@Override
+	public R cmdExecute(DeployAppsVO deployAppsVO) throws ServiceException {
+		String excuteRes = "";
+		try {
+			List<DeployApps> deployAppsDB = deployAppsMapper.selectList(Wrappers.<DeployApps>query().lambda().eq(DeployApps::getServerName, deployAppsVO.getName()));
+			if(deployAppsDB.isEmpty()){
+				return R.fail("鍛戒护鎵ц鍑洪敊锛屽簱涓湭鎵惧埌"+ deployAppsVO.getName() +"鏈嶅姟鐩稿叧閰嶇疆锛�" );
+			}
+			excuteRes = execute(deployAppsDB.get(0),deployAppsVO.getStatus());
+			return R.success("鍛戒护鎵ц缁撴潫锛�"+excuteRes);
+		}catch (Exception e){
+			throw new ServiceException(e.getMessage());
+		}
+	}
+
+	/**
+	 * 鎵ц鍛戒护
+	 * @param deployApps
+	 * @return
+	 * @throws ServiceException
+	 */
+	public String execute(DeployApps deployApps,String type) throws ServiceException {
+		// 澶勭悊涓婁紶鏂囦欢鐨勯�昏緫
+		StringBuilder output = new StringBuilder();
+		try {
+			String cmd = "";
+			if(type.equalsIgnoreCase("UP")){
+				cmd = deployApps.getRestartCmd();
+			}else {
+				cmd = deployApps.getStartCmd();
+			}
+			if(Func.isEmpty(cmd)){
+				return "The executed command is empty";
+			}
+			if(checkCmdVer(cmd)){
+				return "閰嶇疆鐨勫懡浠や腑鍖呭惈鍗遍櫓鍛戒护锛屽锛歳m銆乵v銆乺m -rf銆乧hmod绛夊懡浠ゅ拰鍏抽敭璇嶏紒 ";
+			}
+			// 鎵цLinux鍛戒护
+			log.info("寮�濮嬫墽琛屽懡浠わ細"+cmd);
+			// Process process = Runtime.getRuntime().exec(cmd);
+			ProcessBuilder processBuilder = new ProcessBuilder(cmd.split("\\s"));
+			// processBuilder.command(cmd);
+			Process process = processBuilder.start();
+			// 绛夊緟鍛戒护鎵ц瀹屾垚
+			int exitCode = process.waitFor();
+
+			InputStream inputStream = process.getInputStream();
+			OutputStream outputStream = process.getOutputStream();
+			InputStream errorStream = process.getErrorStream();
+			// 璇诲彇鍛戒护鎵ц缁撴灉
+			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+			String line;
+			while ((line = reader.readLine()) != null) {
+				output.append(line).append("\n");
+			}
+			reader.close();
+
+			// 璇诲彇鍛戒护鎵ц鐨勯敊璇緭鍑烘祦
+			BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream));
+			StringBuilder errorOutput = new StringBuilder();
+			String errorLine;
+			while ((errorLine = errorReader.readLine()) != null) {
+				errorOutput.append(errorLine).append("\n");
+			}
+			String errorOutputString = errorOutput.toString();
+			errorReader.close();
+
+			log.info("閿欒杈撳嚭锛�" + errorOutputString);
+			int exitValue = process.exitValue();
+			log.info("鍛戒护鎵ц缁撴灉锛�" + output.toString()+":"+exitCode+","+exitValue);
+			return output.toString();
+		}catch (IOException | InterruptedException e){
+			e.printStackTrace();
+			log.error("鍛戒护鎵ц鍑洪敊锛屽師鍥狅細" + e.getMessage());
+			throw new ServiceException("Command execution failed"+e.getMessage());
+		}
+	}
+
+	/**
+	 * 鏂囦欢澶囦唤鎿嶄綔
+	 * @param source 婧愭枃浠�
+	 * @param destination 鏂囦欢澶囦唤璺緞
+	 * @throws IOException
+	 */
+	private void copyFolder(File source, File destination) throws IOException {
+		// 鏂囦欢瀛樺湪鎵嶉渶瑕佸浠�
+		if(source.exists()){
+			if (source.isDirectory()) {
+				if (!destination.exists()) {
+					destination.mkdir();
+				}
+				String[] files = source.list();
+				for (String file : files) {
+					File srcFile = new File(source, file);
+					File destFile = new File(destination, file);
+					copyFolder(srcFile, destFile);
+				}
+			} else {
+				Files.copy(source.toPath(), destination.toPath());
+			}
+		}
 	}
 
 	/**
@@ -93,7 +427,7 @@
 	 * @param serviceId
 	 * @return
 	 */
-	public String getGatewayPort(String serviceId) {
+	private String getGatewayPort(String serviceId) {
 		List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
 		if (!instances.isEmpty()) {
 			ServiceInstance gatewayInstance = instances.get(0);
@@ -102,5 +436,22 @@
 		return "8080";
 	}
 
+	/**
+	 * 鍚姩銆佸仠姝€�侀噸鍚懡浠ゆ牎楠�
+	 * @param cmd
+	 * @return true: 鍖呭惈楂橀闄╁懡浠わ紝 false锛氫笉鍖呭惈
+	 */
+	private boolean checkCmdVer(String cmd){
+		if(Func.isEmpty(cmd)){
+			return false;
+		}
+		String[] highRiskCommands = {"rm", "rmdir", "mv", "unlink", "rm -rf", "mv -rf", "dd", "chmod", "chown", "mkfs", "shutdown", "reboot", "kill"};
+		for(String highRiskCmd : highRiskCommands){
+			if(cmd.contains(highRiskCmd)){
+				return true;
+			}
+		}
+		return false;
+	}
 
 }

--
Gitblit v1.9.3