fix: ASW-164 playbook 添加 cancel 接口
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package net.geedge.api.controller;
|
package net.geedge.api.controller;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base32Codec;
|
import cn.hutool.core.codec.Base32Codec;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
@@ -29,6 +30,8 @@ public class APIController {
|
|||||||
|
|
||||||
private final AdbUtil adbUtil;
|
private final AdbUtil adbUtil;
|
||||||
|
|
||||||
|
static final List<Thread> ACTIVE_TASKS = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public APIController(EnvApiYml envApiYml) {
|
public APIController(EnvApiYml envApiYml) {
|
||||||
this.adbUtil = AdbUtil.getInstance(envApiYml.getAdb(), new CommandExec(null));
|
this.adbUtil = AdbUtil.getInstance(envApiYml.getAdb(), new CommandExec(null));
|
||||||
@@ -305,6 +308,7 @@ public class APIController {
|
|||||||
T.FileUtil.del(destination);
|
T.FileUtil.del(destination);
|
||||||
}
|
}
|
||||||
PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName);
|
PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName);
|
||||||
|
playbookRunnable.setName(T.StrUtil.concat(true, id, "-", apkFile.getName()));
|
||||||
ThreadUtil.execAsync(playbookRunnable);
|
ThreadUtil.execAsync(playbookRunnable);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
@@ -319,6 +323,20 @@ public class APIController {
|
|||||||
return R.ok().putData(status);
|
return R.ok().putData(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/playbook/{id}")
|
||||||
|
public R cancel(@PathVariable("id") String id){
|
||||||
|
if (T.StrUtil.isEmpty(id)) {
|
||||||
|
throw new APIException(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(ACTIVE_TASKS)) {
|
||||||
|
ACTIVE_TASKS.stream().filter(thread -> T.StrUtil.startWith(thread.getName(), id)).forEach(thread -> {
|
||||||
|
log.info(String.format("playbook thread: %s has been canceled", thread.getName()));
|
||||||
|
thread.interrupt();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/playbook/{id}/log")
|
@GetMapping("/playbook/{id}/log")
|
||||||
public R getJobResultLog(@PathVariable("id") String id,
|
public R getJobResultLog(@PathVariable("id") String id,
|
||||||
@@ -388,6 +406,7 @@ public class APIController {
|
|||||||
private File apkFile;
|
private File apkFile;
|
||||||
private String packageName;
|
private String packageName;
|
||||||
private File playbookDir;
|
private File playbookDir;
|
||||||
|
private boolean interrupt;
|
||||||
|
|
||||||
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName) {
|
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName) {
|
||||||
this.envApiYml = envApiYml;
|
this.envApiYml = envApiYml;
|
||||||
@@ -395,10 +414,12 @@ public class APIController {
|
|||||||
this.apkFile = apkFile;
|
this.apkFile = apkFile;
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.playbookDir = playbookDir;
|
this.playbookDir = playbookDir;
|
||||||
|
this.interrupt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
ACTIVE_TASKS.add(this);
|
||||||
File logFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.log");
|
File logFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.log");
|
||||||
File statusFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.json");
|
File statusFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.json");
|
||||||
AdbUtil.CommandResult tcpdumpPackage = null;
|
AdbUtil.CommandResult tcpdumpPackage = null;
|
||||||
@@ -414,6 +435,7 @@ public class APIController {
|
|||||||
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
||||||
|
|
||||||
// install apk
|
// install apk
|
||||||
|
if (interrupt) return;
|
||||||
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true);
|
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true);
|
||||||
if (0 != install.exitCode()) {
|
if (0 != install.exitCode()) {
|
||||||
T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8");
|
||||||
@@ -421,6 +443,7 @@ public class APIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear app data
|
// clear app data
|
||||||
|
if (interrupt) return;
|
||||||
AdbUtil.CommandResult clearData = adbUtil.clearAppData(packageName);
|
AdbUtil.CommandResult clearData = adbUtil.clearAppData(packageName);
|
||||||
if (0 != clearData.exitCode()) {
|
if (0 != clearData.exitCode()) {
|
||||||
T.FileUtil.appendString(String.format("ERROR: Clear %s data error: exit code %s \n", packageName, install.exitCode()), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("ERROR: Clear %s data error: exit code %s \n", packageName, install.exitCode()), logFile, "UTF-8");
|
||||||
@@ -428,6 +451,7 @@ public class APIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// star tcpdump: package name
|
// star tcpdump: package name
|
||||||
|
if (interrupt) return;
|
||||||
tcpdumpPackage = adbUtil.startTcpdump(packageName);
|
tcpdumpPackage = adbUtil.startTcpdump(packageName);
|
||||||
if (0 != tcpdumpPackage.exitCode()) {
|
if (0 != tcpdumpPackage.exitCode()) {
|
||||||
T.FileUtil.appendString(String.format("ERROR: Start tcpdump %s failed: exit code %s \n", packageName, tcpdumpPackage.exitCode()), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("ERROR: Start tcpdump %s failed: exit code %s \n", packageName, tcpdumpPackage.exitCode()), logFile, "UTF-8");
|
||||||
@@ -435,6 +459,7 @@ public class APIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// star tcpdump: all
|
// star tcpdump: all
|
||||||
|
if (interrupt) return;
|
||||||
tcpdumpAll = adbUtil.startTcpdump(T.StrUtil.EMPTY);
|
tcpdumpAll = adbUtil.startTcpdump(T.StrUtil.EMPTY);
|
||||||
if (0 != tcpdumpAll.exitCode()) {
|
if (0 != tcpdumpAll.exitCode()) {
|
||||||
T.FileUtil.appendString(String.format("ERROR: Start tcpdump all failed: exit code %s \n", tcpdumpAll.exitCode()), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("ERROR: Start tcpdump all failed: exit code %s \n", tcpdumpAll.exitCode()), logFile, "UTF-8");
|
||||||
@@ -442,6 +467,7 @@ public class APIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exec playbook
|
// exec playbook
|
||||||
|
if (interrupt) return;
|
||||||
AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(playbookDir.getPath(), logFile);
|
AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(playbookDir.getPath(), logFile);
|
||||||
if (0 != airtestResult.exitCode()) {
|
if (0 != airtestResult.exitCode()) {
|
||||||
T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", airtestResult.exitCode()), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", airtestResult.exitCode()), logFile, "UTF-8");
|
||||||
@@ -449,9 +475,11 @@ public class APIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop package tcpdump
|
// stop package tcpdump
|
||||||
|
if (interrupt) return;
|
||||||
stopTcpdump(tcpdumpPackage, logFile, packageName);
|
stopTcpdump(tcpdumpPackage, logFile, packageName);
|
||||||
|
|
||||||
// stop all tcpdump
|
// stop all tcpdump
|
||||||
|
if (interrupt) return;
|
||||||
stopTcpdump(tcpdumpAll, logFile, T.StrUtil.EMPTY);
|
stopTcpdump(tcpdumpAll, logFile, T.StrUtil.EMPTY);
|
||||||
|
|
||||||
resultMap = T.MapUtil.builder()
|
resultMap = T.MapUtil.builder()
|
||||||
@@ -464,17 +492,28 @@ public class APIController {
|
|||||||
.put("status", "error")
|
.put("status", "error")
|
||||||
.build();
|
.build();
|
||||||
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
||||||
|
|
||||||
AdbUtil.CommandResult packageTcpdump = adbUtil.stopTcpdump(tcpdumpPackage.output());
|
|
||||||
adbUtil.execShellCommand(String.format("shell rm -rf %s", packageTcpdump.output()));
|
|
||||||
AdbUtil.CommandResult allTcpdump = adbUtil.stopTcpdump(tcpdumpAll.output());
|
|
||||||
adbUtil.execShellCommand(String.format("shell rm -rf %s", allTcpdump.output()));
|
|
||||||
} finally {
|
} finally {
|
||||||
|
if (T.StrUtil.isNotEmpty(tcpdumpPackage.output())){
|
||||||
|
AdbUtil.CommandResult packageTcpdump = adbUtil.stopTcpdump(tcpdumpPackage.output());
|
||||||
|
adbUtil.execShellCommand(String.format("shell rm -rf %s", packageTcpdump.output()));
|
||||||
|
}
|
||||||
|
if (T.StrUtil.isNotEmpty(tcpdumpAll.output())){
|
||||||
|
AdbUtil.CommandResult allTcpdump = adbUtil.stopTcpdump(tcpdumpAll.output());
|
||||||
|
adbUtil.execShellCommand(String.format("shell rm -rf %s", allTcpdump.output()));
|
||||||
|
}
|
||||||
adbUtil.stopApp(packageName);
|
adbUtil.stopApp(packageName);
|
||||||
T.FileUtil.appendString(String.format("Job succeeded"), logFile, "UTF-8");
|
T.FileUtil.appendString(String.format("Job succeeded"), logFile, "UTF-8");
|
||||||
|
ACTIVE_TASKS.remove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void interrupt() {
|
||||||
|
super.interrupt();
|
||||||
|
this.interrupt = true;
|
||||||
|
adbUtil.setInterrupt(true);
|
||||||
|
}
|
||||||
|
|
||||||
private void stopTcpdump(AdbUtil.CommandResult tcpdump, File logFile, String packageName) {
|
private void stopTcpdump(AdbUtil.CommandResult tcpdump, File logFile, String packageName) {
|
||||||
// stop tcpdump
|
// stop tcpdump
|
||||||
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(tcpdump.output());
|
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(tcpdump.output());
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import net.geedge.common.Constant;
|
|||||||
import net.geedge.common.RCode;
|
import net.geedge.common.RCode;
|
||||||
import net.geedge.common.T;
|
import net.geedge.common.T;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
@@ -37,6 +35,8 @@ public class AdbUtil {
|
|||||||
|
|
||||||
private CommandExec commandExec;
|
private CommandExec commandExec;
|
||||||
|
|
||||||
|
private boolean interrupt;
|
||||||
|
|
||||||
private ExecutorService threadPool;
|
private ExecutorService threadPool;
|
||||||
|
|
||||||
|
|
||||||
@@ -44,6 +44,10 @@ public class AdbUtil {
|
|||||||
return T.StrUtil.isNotEmpty(this.serial) ? serial : String.format("%s:%s", this.host, this.port);
|
return T.StrUtil.isNotEmpty(this.serial) ? serial : String.format("%s:%s", this.host, this.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInterrupt(boolean interrupt) {
|
||||||
|
this.interrupt = interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
public record CommandResult(Integer exitCode, String output) {
|
public record CommandResult(Integer exitCode, String output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -870,6 +874,10 @@ public class AdbUtil {
|
|||||||
bufferedReader = new BufferedReader(inputStreamReader);
|
bufferedReader = new BufferedReader(inputStreamReader);
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
if (T.ObjectUtil.isNotNull(interrupt) && interrupt){
|
||||||
|
log.info("[PlaybookRunnable] [execPlaybook] [stop exec playbook]");
|
||||||
|
process.destroyForcibly();
|
||||||
|
}
|
||||||
// 处理每一行输出
|
// 处理每一行输出
|
||||||
T.FileUtil.appendString(T.StrUtil.concat(true, line, "\n"), logFile, "UTF-8");
|
T.FileUtil.appendString(T.StrUtil.concat(true, line, "\n"), logFile, "UTF-8");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user