Browse Source

增加本地命令模式

master
liuchen 8 months ago
parent
commit
26115c677f
  1. 6
      pom.xml
  2. 135
      src/main/java/com/win/qad/controller/CommandController.java
  3. 34
      src/main/java/com/win/qad/utils/command/CommandUtil.java
  4. 23
      src/main/java/com/win/qad/utils/shell/ShellUtil.java

6
pom.xml

@ -30,6 +30,12 @@
<version>3.9</version> <version>3.9</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>

135
src/main/java/com/win/qad/controller/CommandController.java

@ -0,0 +1,135 @@
package com.win.qad.controller;
import com.alibaba.fastjson.JSONObject;
import com.win.qad.common.CommonResult;
import com.win.qad.config.ShellConfig;
import com.win.qad.exception.GlobalErrorCodeConstants;
import com.win.qad.utils.ProfileUtil;
import com.win.qad.utils.command.CommandUtil;
import com.win.qad.utils.shell.ShellVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import static com.win.qad.exception.GlobalErrorCodeConstants.EXECUTE_FAIL;
@Slf4j
@RestController
@RequestMapping("/command")
public class CommandController {
private static final Logger logger = LoggerFactory.getLogger("sys-user");
@Autowired
private ShellConfig shellConfig;
/**
* 对外提供一个接口通过header中的interfaceName反射机制调用方法方法必须写到这个controller中并且不用加PostMapping注解
*
* @param request request
* @param body 请求主体
* @return 结果
*/
@PostMapping("/api")
@SuppressWarnings("unchecked")
public CommonResult<String> api(HttpServletRequest request, @RequestBody String body) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String interfaceName = request.getHeader("interface");
String sign = request.getHeader("sign");
String timeStr = request.getHeader("timestamp");
if(timeStr == null || timeStr.isEmpty()) {
return CommonResult.error(GlobalErrorCodeConstants.TIMESTAMP_ERROR);
}
long timestamp = 0;
try {
timestamp = Long.parseLong(timeStr);
} catch (NumberFormatException e) {
return CommonResult.error(GlobalErrorCodeConstants.TIMESTAMP_ERROR);
}
String tmp = interfaceName + body + timestamp;
String computeSign = DigestUtils.md5DigestAsHex(tmp.getBytes());
long tenTimestamp = timestamp + (10 * 60 * 1000); // 计算10分钟后的时间戳
long currentTimestamp = System.currentTimeMillis(); // 获取当前时间戳
//过期
if(timestamp > currentTimestamp || tenTimestamp < currentTimestamp) {
return CommonResult.error(GlobalErrorCodeConstants.EXPIRE_ERROR);
}
List<String> activeProfile = ProfileUtil.getActiveProfile();
//dev环境不校验签名
if(!activeProfile.contains("dev") && !StringUtils.equals(sign, computeSign.toUpperCase())) {
return CommonResult.error(GlobalErrorCodeConstants.SIGN_ERROR);
}
Method method = this.getClass().getMethod(interfaceName, String.class);
return (CommonResult<String>) method.invoke(this, body);
}
public CommonResult<String> itemmastercreate(String body) throws IOException, InterruptedException {
String result = CommandUtil.execute("cmd /c ping www.baidu.com -n 5");
return CommonResult.success(result);
}
public CommonResult<String> itemdetailcreate(String body) throws IOException, InterruptedException {
String result = CommandUtil.execute("cmd dir");
return CommonResult.success(result);
}
public CommonResult<String> discretepo(String body) throws IOException, InterruptedException {
JSONObject jsonObject = JSONObject.parseObject(body);
jsonObject = JSONObject.parseObject(jsonObject.getString("dsDescreteOrder"));
ShellVo shellVo;
if(jsonObject.getString("domain") != null && jsonObject.getString("domain").equals("JLHT2")) {
shellVo = shellConfig.getJlht2();
} else {
shellVo = shellConfig.getJlht();
}
//生成traceid
String traceid = jsonObject.getString("traceid");
jsonObject.remove("traceid");
jsonObject.remove("company");
jsonObject.remove("domain");
String inJson = "{\"dsDescreteOrder\":"+ jsonObject+"}";
log.info("inJson: {}", inJson);
//写入json
String result = CommandUtil.execute("touch /home/mfg/work/cim/po/"+traceid+".json && echo '"+inJson+"'>/home/mfg/work/cim/po/"+traceid+".json");
log.info("write json result : " + result);
//写入dat.json
String datJson = "\"/home/mfg/work/cim/po/"+traceid+".json\" \"xxdspoapi.p\" \"/home/mfg/work/out/po/"+traceid+".out.log\" \""+shellVo.getQadUser()+"\" \""+shellVo.getQadPassword()+"\"\r\n\""+shellVo.getQadDomain()+"\"";
log.info("datJson: {}", datJson);
result = CommandUtil.execute("touch /home/mfg/work/cim/po/"+traceid+".dat && echo '"+datJson+"'>/home/mfg/work/cim/po/"+traceid+".dat");
log.info("write dat json result : " + result);
//写入执行文件
String pJson = "output to /home/mfg/work/out/po/" + traceid + ".run.log.\r\n" +
"input from /home/mfg/work/cim/po/" + traceid + ".dat.\r\n" +
"run /home/mfg/work/scripts/xxcommon01.p.\r\n" +
"input close.\r\n" +
"output close.";
log.info("pJson: {}", pJson);
result = CommandUtil.execute("touch /home/mfg/work/cim/po/"+traceid+".p && echo '"+pJson+"'>/home/mfg/work/cim/po/"+traceid+".p");
log.info("write p result : " + result);
//执行QAD脚本
result = CommandUtil.execute("/home/mfg/work/scripts/client-ch-cimload /home/mfg/work/cim/po/"+traceid+".p");
log.info("execute client-ch-loaddata : " + result);
result = CommandUtil.execute("cat /home/mfg/work/out/po/" + traceid + ".run.out.json");
log.info("cat execute log : " + result);
if(result.indexOf("\"SUCCESS\"") > 0) {
//移动执行结果文件
CommandUtil.execute("mv /home/mfg/work/out/po/" + traceid + ".run.out.json /home/mfg/work/success/po/" + traceid + ".run.out.json");
return CommonResult.success(traceid);
}
CommandUtil.execute("mv /home/mfg/work/out/po/" + traceid + ".run.out.json /home/mfg/work/err/po/" + traceid + ".run.out.json");
return CommonResult.error(EXECUTE_FAIL.getCode(), result);
}
}

34
src/main/java/com/win/qad/utils/command/CommandUtil.java

@ -0,0 +1,34 @@
package com.win.qad.utils.command;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class CommandUtil {
/**
* 执行系统命令
* @param command 命令
* @throws IOException
* @throws InterruptedException
*/
public static String execute(String command) throws IOException, InterruptedException {
// 构建CommandLine对象
CommandLine commandLine = CommandLine.parse(command);
// 构建DefaultExecutor对象
DefaultExecutor defaultExecutor = new DefaultExecutor();
// 构建ByteArrayOutputStream对象
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 构建PumpStreamHandler对象
PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(byteArrayOutputStream);
defaultExecutor.setStreamHandler(pumpStreamHandler);
// 开始执行命令
defaultExecutor.execute(commandLine);
// 返回Linux命令执行的结果
return byteArrayOutputStream.toString();
}
}

23
src/main/java/com/win/qad/utils/shell/ShellUtil.java

@ -14,8 +14,17 @@ import java.util.concurrent.ConcurrentHashMap;
@Component @Component
public class ShellUtil { public class ShellUtil {
/**
* 缓存session
*/
protected ConcurrentHashMap<String, Session> sessionConcurrentHashMap = new ConcurrentHashMap<>(); protected ConcurrentHashMap<String, Session> sessionConcurrentHashMap = new ConcurrentHashMap<>();
/**
* 获取linux连接
* @param shellVo
* @return
* @throws JSchException
*/
public Session getShellSession(ShellVo shellVo) throws JSchException { public Session getShellSession(ShellVo shellVo) throws JSchException {
Session session = this.sessionConcurrentHashMap.get(shellVo.getQadDomain()); Session session = this.sessionConcurrentHashMap.get(shellVo.getQadDomain());
if(session == null || !session.isConnected()) { if(session == null || !session.isConnected()) {
@ -27,6 +36,14 @@ public class ShellUtil {
} }
} }
/**
* 执行linux命令
* @param session
* @param command
* @return
* @throws JSchException
* @throws IOException
*/
public String execute(Session session, String command) throws JSchException, IOException { public String execute(Session session, String command) throws JSchException, IOException {
// 创建SSH Channel // 创建SSH Channel
Channel channel = session.openChannel("exec"); Channel channel = session.openChannel("exec");
@ -53,6 +70,12 @@ public class ShellUtil {
return result; return result;
} }
/**
* 创建linux连接
* @param shellVo
* @return
* @throws JSchException
*/
protected Session createSession(ShellVo shellVo) throws JSchException { protected Session createSession(ShellVo shellVo) throws JSchException {
// 创建JSch实例 // 创建JSch实例
JSch jsch = new JSch(); JSch jsch = new JSch();

Loading…
Cancel
Save