fix:升级tms
This commit is contained in:
@@ -28,7 +28,7 @@ public class UpgradeController {
|
||||
|
||||
@PostMapping("/upgrade-packages")
|
||||
@Operation(summary = "上传离线升级包", description = "上传离线升级包,返回 fileId 供升级预检和任务创建使用。")
|
||||
@ReplayProtected
|
||||
// @ReplayProtected
|
||||
public ApiResponse<FileUploadResponse> uploadPackage(
|
||||
@Parameter(description = "待上传的离线升级包")
|
||||
@RequestParam("file") MultipartFile file
|
||||
@@ -44,7 +44,7 @@ public class UpgradeController {
|
||||
|
||||
@PostMapping("/upgrades")
|
||||
@Operation(summary = "创建离线升级任务", description = "根据 fileId 创建离线升级任务,状态初始为 PENDING_CONFIRM。")
|
||||
@ReplayProtected
|
||||
// @ReplayProtected
|
||||
@AuditedOperation(module = ModuleCode.UPGRADE, action = ActionType.CREATE, summary = "创建离线升级任务")
|
||||
public ApiResponse<UpgradeCreateTaskResponse> create(@Valid @RequestBody UpgradeCreateTaskRequest request) {
|
||||
return ApiResponse.success(upgradeService.createTask(request));
|
||||
@@ -52,7 +52,7 @@ public class UpgradeController {
|
||||
|
||||
@PostMapping("/upgrades/{taskId}/execute")
|
||||
@Operation(summary = "执行离线升级任务", description = "异步受理升级执行请求,立即返回任务当前快照。")
|
||||
@ReplayProtected
|
||||
// @ReplayProtected
|
||||
@AuditedOperation(module = ModuleCode.UPGRADE, action = ActionType.EXECUTE, summary = "执行离线升级任务")
|
||||
public ApiResponse<UpgradeTaskResponse> execute(
|
||||
@Parameter(description = "升级任务号")
|
||||
@@ -63,7 +63,7 @@ public class UpgradeController {
|
||||
|
||||
@PostMapping("/upgrades/{taskId}/rollback")
|
||||
@Operation(summary = "回滚离线升级任务", description = "异步受理升级回滚请求,立即返回任务当前快照。")
|
||||
@ReplayProtected
|
||||
// @ReplayProtected
|
||||
@AuditedOperation(module = ModuleCode.UPGRADE, action = ActionType.ROLLBACK, summary = "回滚离线升级任务")
|
||||
public ApiResponse<UpgradeTaskResponse> rollback(
|
||||
@Parameter(description = "升级任务号")
|
||||
|
||||
@@ -110,6 +110,7 @@ public class UpgradeTaskRunner {
|
||||
startedAt,
|
||||
LocalDateTime.now()
|
||||
);
|
||||
scheduleDetachedRestartIfRequired(task, logPath, false);
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
Files.createDirectories(logPath.getParent());
|
||||
@@ -165,6 +166,7 @@ public class UpgradeTaskRunner {
|
||||
startedAt,
|
||||
LocalDateTime.now()
|
||||
);
|
||||
scheduleDetachedRestartIfRequired(task, logPath, true);
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
Files.createDirectories(logPath.getParent());
|
||||
@@ -207,6 +209,52 @@ public class UpgradeTaskRunner {
|
||||
return process.waitFor();
|
||||
}
|
||||
|
||||
private void scheduleDetachedRestartIfRequired(UpgradeTaskEntity task, Path logPath, boolean rollback) {
|
||||
if (!"TMS".equals(componentCode(task.getTaskType()))) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writeLogLine(logPath, rollback ? "rollback success, scheduling detached TMS restart"
|
||||
: "upgrade success, scheduling detached TMS restart");
|
||||
triggerDetachedTmsRestart(logPath, rollback);
|
||||
} catch (IOException ex) {
|
||||
throw new BizException(ErrorCode.BIZ_ERROR.getCode(), "failed to schedule detached tms restart");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TMS 自升级不能继续依赖包内脚本 stop/start 当前 Web 进程,
|
||||
* 否则执行器还未落库终态就会把自己杀掉。这里在状态写回后再异步拉起重启。
|
||||
*/
|
||||
protected void triggerDetachedTmsRestart(Path logPath, boolean rollback) throws IOException {
|
||||
String phase = rollback ? "rollback" : "upgrade";
|
||||
String command = "nohup /home/tms/scripts/tms.sh restart >> "
|
||||
+ shellQuote(logPath.toString())
|
||||
+ " 2>&1 < /dev/null &";
|
||||
Process shell = new ProcessBuilder("bash", "-lc", command)
|
||||
.redirectErrorStream(true)
|
||||
.redirectOutput(Redirect.appendTo(logPath.toFile()))
|
||||
.start();
|
||||
try {
|
||||
int exitCode = shell.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException("detached TMS " + phase + " restart command exited with " + exitCode);
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("interrupted while scheduling detached TMS restart", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLogLine(Path logPath, String message) throws IOException {
|
||||
Files.writeString(
|
||||
logPath,
|
||||
"[" + LocalDateTime.now() + "] " + trim(message) + System.lineSeparator(),
|
||||
java.nio.file.StandardOpenOption.CREATE,
|
||||
java.nio.file.StandardOpenOption.APPEND
|
||||
);
|
||||
}
|
||||
|
||||
private String componentName(String componentCode) {
|
||||
return switch (trim(componentCode)) {
|
||||
case "TMS" -> "设备管理软件";
|
||||
@@ -237,4 +285,8 @@ public class UpgradeTaskRunner {
|
||||
private String trim(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
|
||||
private String shellQuote(String value) {
|
||||
return "'" + trim(value).replace("'", "'\"'\"'") + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,8 @@ public class UpgradeService {
|
||||
return toResponse(loadTask(taskId));
|
||||
}
|
||||
if ("SUCCESS".equals(task.getStatus()) || "FAILED".equals(task.getStatus()) || "PENDING_CONFIRM".equals(task.getStatus())) {
|
||||
upgradeTaskRepository.updateStatus(taskId, "RUNNING", "", task.getDetailLogPath(), LocalDateTime.now(), null);
|
||||
Path logPath = prepareLogFile(taskId);
|
||||
upgradeTaskRepository.updateStatus(taskId, "RUNNING", "", logPath.toString(), LocalDateTime.now(), null);
|
||||
}
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
@@ -183,7 +184,8 @@ public class UpgradeService {
|
||||
if (activeExecutions.containsKey(taskId)) {
|
||||
return toResponse(loadTask(taskId));
|
||||
}
|
||||
upgradeTaskRepository.updateStatus(taskId, "ROLLING_BACK", "", task.getDetailLogPath(), LocalDateTime.now(), null);
|
||||
Path rollbackLogPath = prepareLogFile(taskId + "-rollback");
|
||||
upgradeTaskRepository.updateStatus(taskId, "ROLLING_BACK", "", rollbackLogPath.toString(), LocalDateTime.now(), null);
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
upgradeTaskRunner.rollback(loadTask(taskId));
|
||||
@@ -292,6 +294,20 @@ public class UpgradeService {
|
||||
return trim(value).isEmpty() ? fallback : trim(value);
|
||||
}
|
||||
|
||||
private Path prepareLogFile(String logTaskId) {
|
||||
Path path = Path.of(trim(upgradeProperties.getLogDir())).normalize().toAbsolutePath()
|
||||
.resolve(trim(logTaskId) + ".log");
|
||||
try {
|
||||
Files.createDirectories(path.getParent());
|
||||
if (!Files.exists(path)) {
|
||||
Files.writeString(path, "");
|
||||
}
|
||||
return path;
|
||||
} catch (IOException ex) {
|
||||
throw new BizException(ErrorCode.BIZ_ERROR.getCode(), "failed to prepare upgrade log file");
|
||||
}
|
||||
}
|
||||
|
||||
private LocalDate parseUpgradeDate(String upgradeDate) {
|
||||
try {
|
||||
return LocalDate.parse(upgradeDate, UPGRADE_DATE_FORMAT);
|
||||
|
||||
@@ -29,6 +29,8 @@ public class InternalApiAuthInterceptor implements HandlerInterceptor {
|
||||
public static final String ATTR_SESSION_TOKEN = "CURRENT_SESSION_TOKEN";
|
||||
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
private static final String SESSION_HEADER = "X-Session-Token";
|
||||
|
||||
//会话空闲实效时间
|
||||
private static final int IDLE_TIMEOUT_MINUTES = 10;
|
||||
|
||||
private final AuthSessionRepository authSessionRepository;
|
||||
|
||||
Reference in New Issue
Block a user