task-158: 结果存在文件缺失巡检(resultFileUrl 对应 OSS 文件缺失检出、空白 URL 不告警、只读、可重复)+ 8 条测试
This commit is contained in:
+80
@@ -0,0 +1,80 @@
|
||||
package com.nanri.aiimage.modules.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.nanri.aiimage.modules.file.service.oss.OssStorageService;
|
||||
import com.nanri.aiimage.modules.task.mapper.FileResultMapper;
|
||||
import com.nanri.aiimage.modules.task.model.entity.FileResultEntity;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 结果存在文件缺失巡检(task-158)。
|
||||
*
|
||||
* 只读巡检:file_result 的 resultFileUrl 非空但对应文件在 OSS 不存在的清单输出
|
||||
* 报表;空白 URL 行视为"未生成文件"状态、不告警(历史/失败任务无文件属正常);
|
||||
* 绝不修改任何状态。可重复执行。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ResultFileMissingInspector {
|
||||
|
||||
private final FileResultMapper fileResultMapper;
|
||||
private final OssStorageService ossStorageService;
|
||||
|
||||
public record MissingFileEntry(Long resultId, Long taskId, String moduleType, String resultFileUrl) {
|
||||
}
|
||||
|
||||
public record MissingFileReport(List<MissingFileEntry> entries) {
|
||||
|
||||
public boolean isEmpty() {
|
||||
return entries == null || entries.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public MissingFileReport inspectResultsMissingFile(int limit) {
|
||||
return inspectResultsMissingFile(limit, ossStorageService::objectExists);
|
||||
}
|
||||
|
||||
MissingFileReport inspectResultsMissingFile(int limit, Predicate<String> urlExists) {
|
||||
List<FileResultEntity> results = fileResultMapper.selectList(new LambdaQueryWrapper<FileResultEntity>()
|
||||
.isNotNull(FileResultEntity::getResultFileUrl)
|
||||
.last("limit " + Math.max(1, Math.min(limit, 500))));
|
||||
if (results == null || results.isEmpty()) {
|
||||
return new MissingFileReport(List.of());
|
||||
}
|
||||
List<MissingFileEntry> entries = new ArrayList<>();
|
||||
for (FileResultEntity result : results) {
|
||||
String url = result.getResultFileUrl();
|
||||
if (url == null || url.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
boolean exists;
|
||||
try {
|
||||
exists = urlExists.test(url);
|
||||
} catch (Exception ex) {
|
||||
log.warn("result file existence check failed resultId={} url={} err={}",
|
||||
result.getId(), url, ex.getMessage());
|
||||
continue;
|
||||
}
|
||||
if (!exists) {
|
||||
entries.add(new MissingFileEntry(
|
||||
result.getId(), result.getTaskId(), result.getModuleType(), url));
|
||||
}
|
||||
}
|
||||
MissingFileReport report = new MissingFileReport(List.copyOf(entries));
|
||||
if (!report.isEmpty()) {
|
||||
log.info("result-missing-file report: count={}", report.entries().size());
|
||||
for (MissingFileEntry entry : report.entries()) {
|
||||
log.info("result-missing-file: resultId={} taskId={} moduleType={} url={}",
|
||||
entry.resultId(), entry.taskId(), entry.moduleType(), entry.resultFileUrl());
|
||||
}
|
||||
}
|
||||
return report;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user