fix:回写恢复记录

This commit is contained in:
waner 2026-05-22 16:55:02 +08:00
parent 6cf9bae121
commit 722106edc7
2 changed files with 64 additions and 1 deletions

View File

@ -10,6 +10,8 @@ import com.cisd.tms.modules.backup.service.ResourceTaskQueryService;
import java.nio.file.Path;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.Optional;
@ -41,6 +43,7 @@ public class ResourceTaskQueryServiceImpl implements ResourceTaskQueryService {
RestoreStatusSnapshot status = restoreStatusFileReader.read(resolveTaskDir(active.getRunnerStatePath()));
String latestStatus = defaultIfBlank(status.status(), active.getStatus());
repairMissingTask(active, status, latestStatus);
syncExistingTask(active.getTaskId(), status, latestStatus);
ResourceRestoreLatestResponse response = new ResourceRestoreLatestResponse();
response.setTaskId(active.getTaskId());
response.setBackupId(active.getBackupId());
@ -65,6 +68,7 @@ public class ResourceTaskQueryServiceImpl implements ResourceTaskQueryService {
}
RestoreStatusSnapshot status = restoreStatusFileReader.read(resolveTaskDir(entity));
String latestStatus = defaultIfBlank(status.status(), entity.getStatus());
syncExistingTask(entity, status, latestStatus);
response.setTaskId(entity.getTaskId());
response.setBackupId(entity.getBackupId());
response.setStatus(latestStatus);
@ -109,6 +113,25 @@ public class ResourceTaskQueryServiceImpl implements ResourceTaskQueryService {
resourceRestoreTaskRepository.save(entity);
}
private void syncExistingTask(String taskId, RestoreStatusSnapshot status, String latestStatus) {
if (trim(taskId).isEmpty()) {
return;
}
resourceRestoreTaskRepository.findByTaskId(taskId)
.ifPresent(entity -> syncExistingTask(entity, status, latestStatus));
}
private void syncExistingTask(ResourceRestoreTaskEntity entity, RestoreStatusSnapshot status, String latestStatus) {
if (entity == null || !isTerminal(latestStatus) || latestStatus.equalsIgnoreCase(trim(entity.getStatus()))) {
return;
}
entity.setStatus(latestStatus);
entity.setErrorMessage(status.message());
entity.setFinishTime(parseLocalDateTime(status.updatedAt(), entity.getFinishTime()));
entity.setUpdateTime(LocalDateTime.now());
resourceRestoreTaskRepository.update(entity);
}
private Path resolveStatePath(String statusFilePath) {
return trim(statusFilePath).isEmpty() ? null : Path.of(statusFilePath).normalize();
}
@ -157,7 +180,11 @@ public class ResourceTaskQueryServiceImpl implements ResourceTaskQueryService {
try {
return LocalDateTime.parse(text);
} catch (DateTimeException ex) {
return fallback;
try {
return OffsetDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")).toLocalDateTime();
} catch (DateTimeException ignored) {
return fallback;
}
}
}

View File

@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -61,6 +62,41 @@ class ResourceTaskQueryServiceTest {
));
}
@Test
void shouldSyncExistingRestoreTaskWhenStatusFileIsTerminal() throws Exception {
Path taskDir = tempDir.resolve("RRST-TASK-20260429-000001");
Files.createDirectories(taskDir);
Files.writeString(taskDir.resolve("status.json"), """
{
"status":"SUCCESS",
"phase":"DONE",
"message":"restore applied",
"updatedAt":"2026-05-22T16:16:01+0800"
}
""");
ResourceRestoreTaskEntity entity = restoreTask(taskDir);
ResourceRestoreTaskRepository repository = Mockito.mock(ResourceRestoreTaskRepository.class);
Mockito.when(repository.findAll()).thenReturn(List.of(entity));
ResourceTaskQueryService service = new ResourceTaskQueryServiceImpl(
repository,
new RestoreStatusFileReader(new ObjectMapper()),
new ActiveRestoreStateStore(resourceBackupProperties(), new ObjectMapper())
);
ResourceRestoreLatestResponse latest = service.getLatestRestore();
Assertions.assertEquals("SUCCESS", latest.getStatus());
Assertions.assertEquals("DONE", latest.getPhase());
Assertions.assertEquals("restore applied", latest.getMessage());
Assertions.assertEquals("2026-05-22T16:16:01+0800", latest.getFinishedAt());
Mockito.verify(repository).update(Mockito.argThat(updated ->
"RRST-TASK-20260429-000001".equals(updated.getTaskId())
&& "SUCCESS".equals(updated.getStatus())
&& "restore applied".equals(updated.getErrorMessage())
&& updated.getFinishTime() != null
));
}
private static ResourceRestoreTaskEntity restoreTask(Path taskDir) {
ResourceRestoreTaskEntity entity = new ResourceRestoreTaskEntity();
entity.setTaskId("RRST-TASK-20260429-000001");