추론관리 분석결과 목록조회 추가
This commit is contained in:
@@ -39,10 +39,10 @@ public class GeoJsonFileMonitorService {
|
||||
public void initializeDirectories() {
|
||||
try {
|
||||
log.info("GeoJSON 모니터링 시스템 초기화 중...");
|
||||
log.info("설정된 경로 - Watch: {}, Processed: {}, Error: {}, Temp: {}",
|
||||
config.getWatchDirectory(), config.getProcessedDirectory(),
|
||||
log.info("설정된 경로 - Watch: {}, Processed: {}, Error: {}, Temp: {}",
|
||||
config.getWatchDirectory(), config.getProcessedDirectory(),
|
||||
config.getErrorDirectory(), config.getTempDirectory());
|
||||
|
||||
|
||||
ensureDirectoriesExist();
|
||||
log.info("GeoJSON 모니터링 시스템 초기화 완료");
|
||||
} catch (Exception e) {
|
||||
@@ -55,26 +55,26 @@ public class GeoJsonFileMonitorService {
|
||||
* 스케줄러를 통한 파일 모니터링
|
||||
* 설정된 cron 표현식에 따라 주기적으로 실행
|
||||
*/
|
||||
@Scheduled(cron = "#{@geoJsonMonitorConfig.cronExpression}")
|
||||
// @Scheduled(cron = "#{@geoJsonMonitorConfig.cronExpression}")
|
||||
public void monitorFiles() {
|
||||
log.debug("파일 모니터링 시작");
|
||||
|
||||
|
||||
try {
|
||||
// 모니터링 폴더 존재 확인 및 생성
|
||||
ensureDirectoriesExist();
|
||||
|
||||
|
||||
// 압축파일 검색 및 처리
|
||||
processArchiveFiles();
|
||||
|
||||
|
||||
// 미처리된 Geometry 변환 작업 수행
|
||||
processUnprocessedGeometryData();
|
||||
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
log.error("파일 모니터링 중 치명적 오류 발생 - 이번 주기 건너뜀", e);
|
||||
} catch (Exception e) {
|
||||
log.error("파일 모니터링 중 오류 발생", e);
|
||||
}
|
||||
|
||||
|
||||
log.debug("파일 모니터링 완료");
|
||||
}
|
||||
|
||||
@@ -89,28 +89,28 @@ public class GeoJsonFileMonitorService {
|
||||
log.error("Watch 디렉토리 생성 실패: {} - {}", config.getWatchDirectory(), e.getMessage());
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
createDirectoryIfNotExists(config.getProcessedDirectory());
|
||||
} catch (IOException e) {
|
||||
log.error("Processed 디렉토리 생성 실패: {} - {}", config.getProcessedDirectory(), e.getMessage());
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
createDirectoryIfNotExists(config.getErrorDirectory());
|
||||
} catch (IOException e) {
|
||||
log.error("Error 디렉토리 생성 실패: {} - {}", config.getErrorDirectory(), e.getMessage());
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
createDirectoryIfNotExists(config.getTempDirectory());
|
||||
} catch (IOException e) {
|
||||
log.error("Temp 디렉토리 생성 실패: {} - {}", config.getTempDirectory(), e.getMessage());
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
|
||||
if (hasError) {
|
||||
log.warn("일부 디렉토리 생성에 실패했습니다. 해당 기능은 제한될 수 있습니다.");
|
||||
log.info("수동으로 다음 디렉토리들을 생성해주세요:");
|
||||
@@ -130,14 +130,14 @@ public class GeoJsonFileMonitorService {
|
||||
if (directory == null || directory.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("디렉토리 경로가 비어있습니다.");
|
||||
}
|
||||
|
||||
|
||||
Path path = Paths.get(directory);
|
||||
|
||||
|
||||
if (!Files.exists(path)) {
|
||||
try {
|
||||
Files.createDirectories(path);
|
||||
log.info("디렉토리 생성 완료: {}", directory);
|
||||
|
||||
|
||||
// 디렉토리 권한 설정 (Unix/Linux 환경에서)
|
||||
try {
|
||||
if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
|
||||
@@ -149,7 +149,7 @@ public class GeoJsonFileMonitorService {
|
||||
} catch (Exception permissionException) {
|
||||
log.debug("권한 설정 실패 (무시됨): {}", permissionException.getMessage());
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("디렉토리 생성 실패: {} - {}", directory, e.getMessage());
|
||||
throw new IOException("디렉토리를 생성할 수 없습니다: " + directory, e);
|
||||
@@ -168,29 +168,29 @@ public class GeoJsonFileMonitorService {
|
||||
*/
|
||||
private void processArchiveFiles() {
|
||||
Path watchDir = Paths.get(config.getWatchDirectory());
|
||||
|
||||
|
||||
// 디렉토리 존재 확인
|
||||
if (!Files.exists(watchDir)) {
|
||||
log.debug("Watch 디렉토리가 존재하지 않습니다: {}", watchDir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!Files.isDirectory(watchDir)) {
|
||||
log.warn("Watch 경로가 디렉토리가 아닙니다: {}", watchDir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!Files.isReadable(watchDir)) {
|
||||
log.warn("Watch 디렉토리에 읽기 권한이 없습니다: {}", watchDir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try (Stream<Path> files = Files.list(watchDir)) {
|
||||
files.filter(Files::isRegularFile)
|
||||
.filter(archiveExtractorService::isSupportedArchive)
|
||||
.filter(archiveExtractorService::isFileSizeValid)
|
||||
.forEach(this::processArchiveFile);
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("파일 목록 조회 실패: {}", watchDir, e);
|
||||
}
|
||||
@@ -202,42 +202,42 @@ public class GeoJsonFileMonitorService {
|
||||
private void processArchiveFile(Path archiveFile) {
|
||||
String fileName = archiveFile.getFileName().toString();
|
||||
log.info("압축파일 처리 시작: {}", fileName);
|
||||
|
||||
|
||||
try {
|
||||
// 1. 압축파일에서 GeoJSON 파일들 추출
|
||||
Map<String, String> geoJsonContents = archiveExtractorService.extractGeoJsonFiles(archiveFile);
|
||||
|
||||
|
||||
if (geoJsonContents.isEmpty()) {
|
||||
log.warn("압축파일에서 GeoJSON 파일을 찾을 수 없습니다: {}", fileName);
|
||||
moveFileToError(archiveFile, "GeoJSON 파일 없음");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 2. 처리 가능한 파일 수인지 확인
|
||||
if (!geoJsonDataService.isProcessable(geoJsonContents)) {
|
||||
log.warn("처리할 수 없는 파일입니다: {}", fileName);
|
||||
moveFileToError(archiveFile, "처리 불가능한 파일");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 3. GeoJSON 데이터를 데이터베이스에 저장
|
||||
List<Long> savedLearnDataIds = geoJsonDataService.processGeoJsonFiles(geoJsonContents, fileName);
|
||||
|
||||
|
||||
if (savedLearnDataIds.isEmpty()) {
|
||||
log.warn("저장된 학습 데이터가 없습니다: {}", fileName);
|
||||
moveFileToError(archiveFile, "데이터 저장 실패");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 4. Geometry 데이터로 변환
|
||||
List<Long> geometryIds = geometryConversionService.convertToGeometryData(savedLearnDataIds);
|
||||
|
||||
|
||||
// 5. 처리 완료된 파일을 처리된 폴더로 이동
|
||||
moveFileToProcessed(archiveFile);
|
||||
|
||||
log.info("압축파일 처리 완료: {} (학습 데이터: {}개, Geometry: {}개)",
|
||||
|
||||
log.info("압축파일 처리 완료: {} (학습 데이터: {}개, Geometry: {}개)",
|
||||
fileName, savedLearnDataIds.size(), geometryIds.size());
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("압축파일 처리 실패: {}", fileName, e);
|
||||
try {
|
||||
@@ -269,7 +269,7 @@ public class GeoJsonFileMonitorService {
|
||||
String fileName = sourceFile.getFileName().toString();
|
||||
String timestampedFileName = addTimestamp(fileName);
|
||||
Path targetPath = Paths.get(config.getProcessedDirectory(), timestampedFileName);
|
||||
|
||||
|
||||
Files.move(sourceFile, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
log.info("파일을 처리된 폴더로 이동: {} -> {}", fileName, timestampedFileName);
|
||||
}
|
||||
@@ -281,16 +281,16 @@ public class GeoJsonFileMonitorService {
|
||||
String fileName = sourceFile.getFileName().toString();
|
||||
String errorFileName = addTimestamp(fileName) + ".error";
|
||||
Path targetPath = Paths.get(config.getErrorDirectory(), errorFileName);
|
||||
|
||||
|
||||
Files.move(sourceFile, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
|
||||
// 오류 정보를 별도 파일로 저장
|
||||
String errorInfoFileName = errorFileName + ".info";
|
||||
Path errorInfoPath = Paths.get(config.getErrorDirectory(), errorInfoFileName);
|
||||
String errorInfo = String.format("파일: %s%n오류 시간: %s%n오류 원인: %s%n",
|
||||
String errorInfo = String.format("파일: %s%n오류 시간: %s%n오류 원인: %s%n",
|
||||
fileName, java.time.Instant.now(), errorReason);
|
||||
Files.write(errorInfoPath, errorInfo.getBytes());
|
||||
|
||||
|
||||
log.warn("파일을 오류 폴더로 이동: {} (원인: {})", fileName, errorReason);
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ public class GeoJsonFileMonitorService {
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
String name = (lastDotIndex > 0) ? fileName.substring(0, lastDotIndex) : fileName;
|
||||
String extension = (lastDotIndex > 0) ? fileName.substring(lastDotIndex) : "";
|
||||
|
||||
|
||||
return String.format("%s_%d%s", name, System.currentTimeMillis(), extension);
|
||||
}
|
||||
|
||||
@@ -310,17 +310,17 @@ public class GeoJsonFileMonitorService {
|
||||
*/
|
||||
public void processFileManually(String filePath) {
|
||||
Path archiveFile = Paths.get(filePath);
|
||||
|
||||
|
||||
if (!Files.exists(archiveFile)) {
|
||||
log.error("파일이 존재하지 않습니다: {}", filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!archiveExtractorService.isSupportedArchive(archiveFile)) {
|
||||
log.error("지원하지 않는 압축파일 형식입니다: {}", filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
log.info("수동 파일 처리 시작: {}", filePath);
|
||||
processArchiveFile(archiveFile);
|
||||
}
|
||||
@@ -359,22 +359,22 @@ public class GeoJsonFileMonitorService {
|
||||
*/
|
||||
public Map<String, Object> getSystemStats() {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
|
||||
|
||||
try {
|
||||
// 데이터베이스 통계
|
||||
long totalLearnData = learnDataRepository.count();
|
||||
long totalGeomData = geomRepository.count();
|
||||
long pendingAnalysis = learnDataRepository.countByAnalState("PENDING");
|
||||
|
||||
|
||||
stats.put("database", Map.of(
|
||||
"totalLearnData", totalLearnData,
|
||||
"totalGeomData", totalGeomData,
|
||||
"pendingAnalysis", pendingAnalysis
|
||||
));
|
||||
|
||||
|
||||
// 파일 시스템 통계
|
||||
stats.put("fileSystem", getFileSystemStats());
|
||||
|
||||
|
||||
// 모니터링 설정
|
||||
stats.put("monitoring", Map.of(
|
||||
"isActive", true,
|
||||
@@ -383,39 +383,39 @@ public class GeoJsonFileMonitorService {
|
||||
"processedDirectory", config.getProcessedDirectory(),
|
||||
"errorDirectory", config.getErrorDirectory()
|
||||
));
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("통계 정보 조회 실패", e);
|
||||
stats.put("error", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 파일 시스템 통계 조회
|
||||
*/
|
||||
private Map<String, Object> getFileSystemStats() {
|
||||
Map<String, Object> fileStats = new HashMap<>();
|
||||
|
||||
|
||||
try {
|
||||
// 각 디렉토리의 파일 수 계산
|
||||
Path watchDir = Paths.get(config.getWatchDirectory());
|
||||
Path processedDir = Paths.get(config.getProcessedDirectory());
|
||||
Path errorDir = Paths.get(config.getErrorDirectory());
|
||||
|
||||
|
||||
fileStats.put("watchDirectoryCount", countFilesInDirectory(watchDir));
|
||||
fileStats.put("processedDirectoryCount", countFilesInDirectory(processedDir));
|
||||
fileStats.put("errorDirectoryCount", countFilesInDirectory(errorDir));
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("파일 시스템 통계 조회 실패: {}", e.getMessage());
|
||||
fileStats.put("error", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
return fileStats;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 디렉토리 내 파일 개수 계산
|
||||
*/
|
||||
@@ -423,7 +423,7 @@ public class GeoJsonFileMonitorService {
|
||||
if (!Files.exists(directory) || !Files.isDirectory(directory)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
try (Stream<Path> files = Files.list(directory)) {
|
||||
return files.filter(Files::isRegularFile).count();
|
||||
} catch (IOException e) {
|
||||
@@ -431,4 +431,4 @@ public class GeoJsonFileMonitorService {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user