From 9855886b4277d156f45a3dedb2a2dd854ca54ccc Mon Sep 17 00:00:00 2001 From: Moon Date: Tue, 16 Dec 2025 09:19:02 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=98=81=EC=83=81=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=8B=B1=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamcoback/common/utils/FIleChecker.java | 179 +++++++++++ .../kamco/cd/kamcoback/config/FileConfig.java | 1 + .../core/MapSheetMngFileJobCoreService.java | 68 ++++ .../MapSheetMngFileJobRepository.java | 9 + .../MapSheetMngFileJobRepositoryCustom.java | 20 ++ .../MapSheetMngFileJobRepositoryImpl.java | 177 +++++++++++ .../MapSheetMngFileJobApiController.java | 53 ++++ .../MapSheetMngFileJobController.java | 116 +++++++ .../cd/kamcoback/scheduler/dto/FileDto.java | 159 ++++++++++ .../scheduler/dto/MapSheetMngDto.java | 129 ++++++++ .../service/MapSheetMngFileJobService.java | 299 ++++++++++++++++++ 11 files changed, 1210 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scheduler/dto/FileDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java index 6702e8cf..895e0c98 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java @@ -1,5 +1,9 @@ package com.kamco.cd.kamcoback.common.utils; +import static java.lang.String.CASE_INSENSITIVE_ORDER; + +import com.kamco.cd.kamcoback.scheduler.dto.FileDto; +import io.swagger.v3.oas.annotations.media.Schema; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -9,10 +13,20 @@ import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.FileTime; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.Getter; +import org.apache.commons.io.FilenameUtils; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.gce.geotiff.GeoTiffReader; @@ -145,8 +159,27 @@ public class FIleChecker { boolean hasDriver = false; List command = new ArrayList<>(); + // 윈도우용 + + command.add("cmd.exe"); // 윈도우 명령 프롬프트 실행 + command.add("/c"); // 명령어를 수행하고 종료한다는 옵션 command.add("gdalinfo"); command.add(filePath); + command.add("|"); + command.add("findstr"); + command.add("/i"); + command.add("Geo"); + + /* + command.add("sh"); // 리눅스,맥 명령 프롬프트 실행 + command.add("-c"); // 명령어를 수행하고 종료한다는 옵션 + command.add("gdalinfo"); + command.add(filePath); + command.add("|"); + command.add("grep"); + command.add("-i"); + command.add("Geo"); + */ ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder.redirectErrorStream(true); @@ -158,6 +191,7 @@ public class FIleChecker { String line; while ((line = reader.readLine()) != null) { + System.out.println("line == " + line); if (line.contains("Driver: GTiff/GeoTIFF")) { hasDriver = true; break; @@ -172,4 +206,149 @@ public class FIleChecker { return hasDriver; } + + + @Schema(name = "File Basic", description = "파일 기본 정보") + @Getter + public static class Basic { + + private final String fileNm; + private final String parentFolderNm; + private final String parentPath; + private final String fullPath; + private final String extension; + private final long fileSize; + private final String lastModified; + + public Basic( + String fileNm, + String parentFolderNm, + String parentPath, + String fullPath, + String extension, + long fileSize, + String lastModified) { + this.fileNm = fileNm; + this.parentFolderNm = parentFolderNm; + this.parentPath = parentPath; + this.fullPath = fullPath; + this.extension = extension; + this.fileSize = fileSize; + this.lastModified = lastModified; + } + } + + + + public static List getFilesFromAllDepth(String dir, String targetFileNm, String extension, int maxDepth, String sortType, int startPos, int limit) { + + Path startPath = Paths.get(dir); + String dirPath = dir; + + Set targetExtensions = createExtensionSet(extension); + + List fileList = new ArrayList<>(); + SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + int fileTotCnt = 0; + long fileTotSize = 0; + + try (Stream stream = Files.walk(startPath, maxDepth)) { + + fileList = + stream + .filter(Files::isRegularFile) + .filter( + p -> + extension == null + || extension.equals("") + || extension.equals("*") + || targetExtensions.contains(extractExtension(p))) + .sorted(getFileComparator(sortType)) + .filter( + p -> p.getFileName().toString().contains(targetFileNm) + ) + .skip(startPos) + .limit(limit) + .map( + path -> { + //int depth = path.getNameCount(); + + String fileNm = path.getFileName().toString(); + String ext = FilenameUtils.getExtension(fileNm); + String parentFolderNm = path.getParent().getFileName().toString(); + String parentPath = path.getParent().toString(); + String fullPath = path.toAbsolutePath().toString(); + + File file = new File(fullPath); + long fileSize = file.length(); + String lastModified = dttmFormat.format(new Date(file.lastModified())); + + return new Basic( + fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); + }) + .collect(Collectors.toList()); + + + } catch (IOException e) { + System.err.println("파일 I/O 오류 발생: " + e.getMessage()); + } + + return fileList; + } + + + public static Set createExtensionSet(String extensionString) { + if (extensionString == null || extensionString.isBlank()) { + return Set.of(); + } + + // "java, class" -> ["java", " class"] -> [".java", ".class"] + return Arrays.stream(extensionString.split(",")) + .map(ext -> ext.trim()) + .filter(ext -> !ext.isEmpty()) + .map(ext -> "." + ext.toLowerCase()) + .collect(Collectors.toSet()); + } + + public static String extractExtension(Path path) { + String filename = path.getFileName().toString(); + int lastDotIndex = filename.lastIndexOf('.'); + + // 확장자가 없거나 파일명이 .으로 끝나는 경우 + if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) { + return ""; // 빈 문자열 반환 + } + + // 확장자 추출 및 소문자 변환 + return filename.substring(lastDotIndex).toLowerCase(); + } + + public static Comparator getFileComparator(String sortType) { + + // 파일 이름 비교 기본 Comparator (대소문자 무시) + Comparator nameComparator = + Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); + + Comparator dateComparator = + Comparator.comparing( + path -> { + try { + return Files.getLastModifiedTime(path); + } catch (IOException e) { + return FileTime.fromMillis(0); + } + }); + + if ("name desc".equalsIgnoreCase(sortType)) { + return nameComparator.reversed(); + } else if ("date".equalsIgnoreCase(sortType)) { + return dateComparator; + } else if ("date desc".equalsIgnoreCase(sortType)) { + return dateComparator.reversed(); + } else { + return nameComparator; + } + } + } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java index d401940d..a7c1ecb0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java @@ -15,4 +15,5 @@ public class FileConfig { private String rootSyncDir = "D:\\app\\original-images"; // private String rootSyncDir = "/app/original-images"; + } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java new file mode 100644 index 00000000..88dd2740 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java @@ -0,0 +1,68 @@ +package com.kamco.cd.kamcoback.postgres.core; + +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngFileEntity; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.postgres.repository.scheduler.MapSheetMngFileJobRepository; +import jakarta.persistence.EntityNotFoundException; +import jakarta.validation.Valid; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MapSheetMngFileJobCoreService { + + private final MapSheetMngFileJobRepository mapSheetMngFileJobRepository; + + public Page findMapSheetMngList( + MapSheetMngDto.@Valid MngSearchReq searchReq) { + return mapSheetMngFileJobRepository.findMapSheetMngList(searchReq); + } + + public List findTargetMapSheetFileList(long targetNum, int pageSize) { + return mapSheetMngFileJobRepository.findTargetMapSheetFileList(targetNum, pageSize); + } + + public MapSheetMngDto.DmlReturn mngHstDataSyncStateUpdate(@Valid MapSheetMngDto.MngHstDto updateReq) { + + mapSheetMngFileJobRepository.mngHstDataSyncStateUpdate(updateReq); + + return new MapSheetMngDto.DmlReturn("success", updateReq.getHstUid()+""); + } + + + public MapSheetMngDto.DmlReturn mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) { + + MapSheetMngFileEntity entity = new MapSheetMngFileEntity(); + entity.setMngYyyy(addReq.getMngYyyy()); + entity.setMapSheetNum(addReq.getMapSheetNum()); + entity.setRefMapSheetNum(addReq.getRefMapSheetNum()); + entity.setFilePath(addReq.getFilePath()); + entity.setFileName(addReq.getFileName()); + entity.setFileExt(addReq.getFileExt()); + entity.setHstUid(addReq.getHstUid()); + entity.setFileSize(addReq.getFileSize()); + entity.setFileState(addReq.getFileState()); + + MapSheetMngFileEntity saved = mapSheetMngFileJobRepository.save(entity); + //int hstCnt = mapSheetMngRepository.insertMapSheetOrgDataToMapSheetMngHst(saved.getMngYyyy()); + + return new MapSheetMngDto.DmlReturn("success", saved.getFileUid().toString()); + } + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java new file mode 100644 index 00000000..7ffffc8d --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java @@ -0,0 +1,9 @@ +package com.kamco.cd.kamcoback.postgres.repository.scheduler; + +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngFileEntity; +import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MapSheetMngFileJobRepository + extends JpaRepository, MapSheetMngFileJobRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java new file mode 100644 index 00000000..45988ed3 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java @@ -0,0 +1,20 @@ +package com.kamco.cd.kamcoback.postgres.repository.scheduler; + +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import jakarta.validation.Valid; +import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; + +public interface MapSheetMngFileJobRepositoryCustom { + + Page findMapSheetMngList(MapSheetMngDto.MngSearchReq searchReq); + + void mngHstDataSyncStateUpdate(MapSheetMngDto.MngHstDto updateReq); + + List findTargetMapSheetFileList(long targetNum, int pageSize); + + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java new file mode 100644 index 00000000..689ac10d --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java @@ -0,0 +1,177 @@ +package com.kamco.cd.kamcoback.postgres.repository.scheduler; + +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngEntity.mapSheetMngEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity; + +import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import java.time.ZonedDateTime; +import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; + +public class MapSheetMngFileJobRepositoryImpl extends QuerydslRepositorySupport + implements MapSheetMngFileJobRepositoryCustom { + + private final JPAQueryFactory queryFactory; + private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); + + @PersistenceContext private EntityManager em; + + public MapSheetMngFileJobRepositoryImpl(JPAQueryFactory queryFactory) { + super(MapSheetMngHstEntity.class); + this.queryFactory = queryFactory; + } + + @Override + public Page findMapSheetMngList(MapSheetMngDto.MngSearchReq searchReq) { + + Pageable pageable = searchReq.toPageable(); + BooleanBuilder whereBuilder = new BooleanBuilder(); + + if (searchReq.getMngYyyy() != null) { + whereBuilder.and(mapSheetMngEntity.mngYyyy.eq(searchReq.getMngYyyy())); + } + + List foundContent = + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngDto.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} desc)", + mapSheetMngEntity.createdDttm), + mapSheetMngEntity.mngYyyy, + mapSheetMngEntity.mngState, + mapSheetMngEntity.syncState, + mapSheetMngEntity.syncCheckState, + mapSheetMngHstEntity.count(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncCheckState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("NOT")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("TYPEERROR")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("SIZEERROR")) + .then(1L) + .otherwise(0L) + .sum(), + mapSheetMngHstEntity.syncStrtDttm.min(), + mapSheetMngHstEntity.syncCheckEndDttm.max())) + .from(mapSheetMngEntity) + .leftJoin(mapSheetMngHstEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where(whereBuilder) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(mapSheetMngEntity.createdDttm.desc()) + .groupBy(mapSheetMngEntity.mngYyyy) + .fetch(); + + Long countQuery = + queryFactory + .select(mapSheetMngEntity.mngYyyy.count()) + .from(mapSheetMngEntity) + .where(whereBuilder) + .fetchOne(); + + return new PageImpl<>(foundContent, pageable, countQuery); + } + + + public void mngHstDataSyncStateUpdate(MapSheetMngDto.MngHstDto updateReq) { + + if( updateReq.getSyncState().equals("DONE") ) { + long updateCount = + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) + .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) + .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) + .execute(); + } + else { + long updateCount = + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) + .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) + .set(mapSheetMngHstEntity.syncStrtDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) + .execute(); + } + + } + + + @Override + public List findTargetMapSheetFileList(long targetNum, int pageSize) + { + //Pageable pageable = searchReq.toPageable(); + + List foundContent = + queryFactory + .select( + Projections.constructor( + MngHstDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + mapSheetMngHstEntity.dataState, + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncStrtDttm, + mapSheetMngHstEntity.syncEndDttm, + mapSheetMngHstEntity.syncCheckStrtDttm, + mapSheetMngHstEntity.syncCheckEndDttm, + + mapSheetMngEntity.mngPath + )) + .from(mapSheetMngHstEntity) + .join(mapSheetMngEntity).on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where( + mapSheetMngHstEntity.syncState.eq("NOTYET"), + mapSheetMngHstEntity.hstUid.mod(10L).eq(targetNum) + ).limit(pageSize) + .orderBy(mapSheetMngHstEntity.hstUid.asc()) + .fetch(); + + return foundContent; + } + + + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java new file mode 100644 index 00000000..190d2420 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java @@ -0,0 +1,53 @@ +package com.kamco.cd.kamcoback.scheduler; + +import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; +import com.kamco.cd.kamcoback.code.service.CommonCodeService; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "스캐쥴러 API", description = "스캐쥴러 API") +@RestController +@RequiredArgsConstructor +@RequestMapping({"/api/job"}) +public class MapSheetMngFileJobApiController { + + private final CommonCodeService commonCodeService; + private final MapSheetMngFileJobController mapSheetMngFileJobController; + + @Operation(summary = "영상관리 파일 싱크 스캐쥴러 Start/Stop", description = "영상관리 파일 싱크 스캐쥴러 Start/Stop API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = CommonCodeDto.Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PutMapping("/mng-sync-job") + public ApiResponseDto mngSyncOnOff( + @RequestParam boolean jobStart, + @RequestParam int pageSize) { + + mapSheetMngFileJobController.setSchedulerEnabled(jobStart); + mapSheetMngFileJobController.setMngSyncPageSize(pageSize); + + return ApiResponseDto.createOK("OK"); + } + + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java new file mode 100644 index 00000000..e5152fa4 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java @@ -0,0 +1,116 @@ +package com.kamco.cd.kamcoback.scheduler; + +import com.kamco.cd.kamcoback.scheduler.service.MapSheetMngFileJobService; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class MapSheetMngFileJobController { + + private final MapSheetMngFileJobService mapSheetMngFileJobService; + + // 현재 상태 확인용 Getter + @Getter + private boolean isSchedulerEnabled = false; + @Getter + private int mngSyncPageSize = 20; + + // 매일 새벽 3시에 실행 (초 분 시 일 월 요일) + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob00() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob00 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(0, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob01() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob01 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(1, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob02() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob00 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(2, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob03() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob03 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(3, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob04() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob04 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(4, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob05() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob05 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(5, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob06() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob06 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(6, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob07() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob07 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(7, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob08() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob08 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(8, mngSyncPageSize); + } + + @Scheduled(fixedDelay = 5000) + public void mngFileSyncJob09() { + if( !isSchedulerEnabled ) return; + + System.out.println("mngFileSyncJob09 === " + System.currentTimeMillis()); + mapSheetMngFileJobService.checkMapSheetFileProcess(9, mngSyncPageSize); + } + + + + // 3. 외부에서 플래그를 변경할 수 있는 Setter 메서드 + public void setSchedulerEnabled(boolean enabled) { + this.isSchedulerEnabled = enabled; + System.out.println("스케줄러 상태 변경됨: "+( enabled ? "ON" : "OFF")); + } + + public void setMngSyncPageSize(int pageSize) { + this.mngSyncPageSize = pageSize; + System.out.println("스케줄러 처리 개수 변경됨: "+pageSize); + } + + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/FileDto.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/FileDto.java new file mode 100644 index 00000000..99cf8b9e --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/FileDto.java @@ -0,0 +1,159 @@ +package com.kamco.cd.kamcoback.scheduler.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +public class FileDto { + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SrchFoldersDto { + @Schema(description = "디렉토리경로(ROOT:/app/original-images)", example = "") + @NotNull + private String dirPath; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SrchFilesDto { + @Schema(description = "디렉토리경로", example = "D:\\kamco\\2022\\캠코_2021_2022_34602060_D1") + @NotNull + private String dirPath; + + @Schema(description = "전체(*), cpg,dbf,geojson등", example = "*") + @NotNull + private String extension; + + @Schema(description = "전체(*), 3878687.tif", example = "*") + @NotNull + private String fileNm; + + @Schema(description = "파일명(name), 최종수정일(date)", example = "name") + @NotNull + private String sortType; + + @Schema(description = "파일시작위치", example = "1") + @NotNull + private Integer startPos = 0; + + @Schema(description = "파일종료위치", example = "100") + @NotNull + private Integer endPos = 100; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SrchFilesDepthDto extends SrchFilesDto { + @Schema(description = "최대폴더Depth", example = "5") + @NotNull + private Integer maxDepth; + } + + @Schema(name = "FolderDto", description = "폴더 정보") + @Getter + public static class FolderDto { + private final String folderNm; + private final String parentFolderNm; + private final String parentPath; + private final String fullPath; + private final int depth; + private final long childCnt; + private final String lastModified; + private final Boolean isValid; + + public FolderDto( + String folderNm, + String parentFolderNm, + String parentPath, + String fullPath, + int depth, + long childCnt, + String lastModified, + Boolean isValid) { + this.folderNm = folderNm; + this.parentFolderNm = parentFolderNm; + this.parentPath = parentPath; + this.fullPath = fullPath; + this.depth = depth; + this.childCnt = childCnt; + this.lastModified = lastModified; + this.isValid = isValid; + } + } + + @Schema(name = "FoldersDto", description = "폴더목록 정보") + @Getter + public static class FoldersDto { + private final String dirPath; + private final int folderTotCnt; + private final int folderErrTotCnt; + private final List folders; + + public FoldersDto( + String dirPath, int folderTotCnt, int folderErrTotCnt, List folders) { + + this.dirPath = dirPath; + this.folderTotCnt = folderTotCnt; + this.folderErrTotCnt = folderErrTotCnt; + this.folders = folders; + } + } + + @Schema(name = "File Basic", description = "파일 기본 정보") + @Getter + public static class Basic { + + private final String fileNm; + private final String parentFolderNm; + private final String parentPath; + private final String fullPath; + private final String extension; + private final long fileSize; + private final String lastModified; + + public Basic( + String fileNm, + String parentFolderNm, + String parentPath, + String fullPath, + String extension, + long fileSize, + String lastModified) { + this.fileNm = fileNm; + this.parentFolderNm = parentFolderNm; + this.parentPath = parentPath; + this.fullPath = fullPath; + this.extension = extension; + this.fileSize = fileSize; + this.lastModified = lastModified; + } + } + + @Schema(name = "FilesDto", description = "파일 목록 정보") + @Getter + public static class FilesDto { + private final String dirPath; + private final int fileTotCnt; + private final long fileTotSize; + private final List files; + + public FilesDto(String dirPath, int fileTotCnt, long fileTotSize, List files) { + + this.dirPath = dirPath; + this.fileTotCnt = fileTotCnt; + this.fileTotSize = fileTotSize; + this.files = files; + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java new file mode 100644 index 00000000..d975b242 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java @@ -0,0 +1,129 @@ +package com.kamco.cd.kamcoback.scheduler.dto; + +import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; +import com.kamco.cd.kamcoback.config.enums.EnumType; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.ZonedDateTime; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +public class MapSheetMngDto { + + @Schema(name = "MngSearchReq", description = "영상관리 검색 요청") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class MngSearchReq { + + // 페이징 파라미터 + @Schema(description = "페이지 번호 (0부터 시작) ", example = "0") + private int page = 0; + + @Schema(description = "페이지 크기", example = "20") + private int size = 20; + + @Schema(description = "년도", example = "2025") + private Integer mngYyyy; + + public Pageable toPageable() { + return PageRequest.of(page, size); + } + } + + @Schema(name = "MngDto", description = "영상관리 검색 리턴") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class MngDto { + private int rowNum; + private int mngYyyy; + private String mngState; + private String syncState; + private String syncCheckState; + private Long syncTotCnt; + private Long syncStateDoneCnt; + private Long syncCheckStateDoneCnt; + private Long syncNotFileCnt; + private Long syncTypeErrorCnt; + private Long syncSizeErrorCnt; + @JsonFormatDttm private ZonedDateTime rgstStrtDttm; + @JsonFormatDttm private ZonedDateTime rgstEndDttm; + } + + @Schema(name = "MngHstDto", description = "영상관리내역 검색 리턴") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class MngHstDto { + private long hstUid; + private int mngYyyy; + private String mapSheetNum; + private String refMapSheetNum; + private String dataState; + private String syncState; + private String syncCheckState; + @JsonFormatDttm private ZonedDateTime syncStrtDttm; + @JsonFormatDttm private ZonedDateTime syncEndDttm; + @JsonFormatDttm private ZonedDateTime syncCheckStrtDttm; + @JsonFormatDttm private ZonedDateTime syncCheckEndDttm; + + private String syncMngPath; + } + + + @Schema(name = "MngFileAddReq", description = "영상관리파일 등록 요청") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class MngFileAddReq { + private int mngYyyy; + private String mapSheetNum; + private String refMapSheetNum; + private String filePath; + private String fileName; + private String fileExt; + private Long hstUid; + private Long fileSize; + private String fileState; + } + + @Schema(name = "MngFilesDto", description = "영상관리내역 검색 리턴") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class MngFilesDto { + private long fileUid; + private int mngYyyy; + private String mapSheetNum; + private String refMapSheetNum; + private String filePath; + private String fileName; + private String fileExt; + private Long hstUid; + private Long fileSize; + } + + + + + @Schema(name = "DmlReturn", description = "영상관리 DML 수행 후 리턴") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class DmlReturn { + private String flag; + private String message; + } + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java new file mode 100644 index 00000000..aed59337 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java @@ -0,0 +1,299 @@ +package com.kamco.cd.kamcoback.scheduler.service; + +import static java.lang.String.CASE_INSENSITIVE_ORDER; + +import com.kamco.cd.kamcoback.scheduler.dto.FileDto; +import com.kamco.cd.kamcoback.scheduler.dto.FileDto.FilesDto; +import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDepthDto; +import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngDto; +import com.kamco.cd.kamcoback.postgres.core.MapSheetMngFileJobCoreService; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; + + +import com.kamco.cd.kamcoback.common.utils.FIleChecker; +import com.kamco.cd.kamcoback.common.utils.NameValidator; +import com.kamco.cd.kamcoback.config.FileConfig; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileTime; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.apache.commons.io.FilenameUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MapSheetMngFileJobService { + + private final MapSheetMngFileJobCoreService mapSheetMngFileJobCoreService; + + @Transactional + public void checkMapSheetFileProcess(long targetNum, int mngSyncPageSize) { + + List mapSheetFileNotYetList = findTargetMapSheetFileList(targetNum, mngSyncPageSize); + + Long hstUid = 0L; + String syncState = ""; + String syncCheckState = ""; + String fileState = ""; + String dataState = ""; + + SrchFilesDepthDto srchDto = new SrchFilesDepthDto(); + List basicList = new ArrayList<>(); + + for (MngHstDto item : mapSheetFileNotYetList) { + + //도엽별 파일 체크 진행중으로 변경 + item.setDataState("PROCESSING"); + mngHstDataSyncStateUpdate(item); + + // 1. MngHstDto 객체의 필드 값에 접근 + //hstUid = item.getHstUid(); + //syncState = item.getSyncState(); + + srchDto.setMaxDepth(10); + srchDto.setDirPath(item.getSyncMngPath()); + srchDto.setExtension("tif,tfw"); + srchDto.setFileNm(item.getMapSheetNum()); + //srchDto.setFileNm("34602047"); + + System.out.println("UID: " + hstUid + ", 상태: " + syncState + ", 관리경로: " + item.getSyncMngPath() + ", 파일명 " + item.getMapSheetNum() + " .tif,tfw"); + + //도엽번호로 파일 찾기 + //basicList = this.getFilesDepthAll(srchDto); + + basicList = FIleChecker.getFilesFromAllDepth(srchDto.getDirPath(), srchDto.getFileNm(), + srchDto.getExtension(), srchDto.getMaxDepth(), srchDto.getSortType(), 0, 100); + + + int tfwCnt = + (int) + basicList.stream() + .filter(dto -> dto.getExtension().toString().equals("tfw")) + .count(); + + int tifCnt = + (int) + basicList.stream() + .filter(dto -> dto.getExtension().toString().equals("tif")) + .count(); + + syncState = ""; + syncCheckState = ""; + + if( tfwCnt == 0 && tifCnt == 0)syncState="NOFILE"; + + for (FIleChecker.Basic item2 : basicList) { + System.out.println("path: " + item2.getParentPath()); + System.out.println("path: " + item2.getFileNm()); + System.out.println("path: " + item2.getFullPath()); + + MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq(); + addReq.setMngYyyy(item.getMngYyyy()); + addReq.setMapSheetNum(item.getMapSheetNum()); + addReq.setRefMapSheetNum(item.getRefMapSheetNum()); + addReq.setFilePath(item2.getParentPath()); + addReq.setFileName(item2.getFileNm()); + addReq.setFileExt(item2.getExtension()); + addReq.setFileSize(item2.getFileSize()); + addReq.setHstUid(item.getHstUid()); + + fileState = "DONE"; + if(item2.getExtension().equals("tfw") ) { + if( tifCnt == 0){fileState = "NOTPAIR";syncState = fileState;} + else if( tfwCnt > 1){fileState = "DUPLICATE";syncState = fileState;} + else if( item2.getFileSize() == 0 ){fileState = "SIZEERROR";syncState = fileState;} + else if( ! FIleChecker.checkTfw(item2.getFullPath()) ){fileState = "TYPEERROR";syncState = fileState;} + } + else if(item2.getExtension().equals("tif") ){ + if( tfwCnt == 0){fileState = "NOTPAIR";syncState = fileState;} + else if( tifCnt > 1){fileState = "DUPLICATE";syncState = fileState;} + else if( item2.getFileSize() == 0 ){fileState = "SIZEERROR";syncState = fileState;} + else if( ! FIleChecker.cmmndGdalInfo(item2.getFullPath()) ){fileState = "TYPEERROR";syncState = fileState;} + } + + addReq.setFileState(fileState); + MapSheetMngDto.DmlReturn DmlReturn = mngDataSave(addReq); + + } + + //도엽별 파일 체크 완료로 변경 + item.setDataState("DONE"); + if(syncState.isEmpty())syncState="DONE"; + item.setSyncState(syncState); + mngHstDataSyncStateUpdate(item); + + //srchDto. + + // 2. 출력 + //System.out.println("UID: " + hstUid + ", 상태: " + syncState + ", 관리경로: " + item.getSyncMngPath()); + + // 3. (필요하다면) 다른 로직 수행 + // ... + } + + + + } + + public int checkIsNoFile(List basicList) + { + if( basicList == null || basicList.size() == 0 ) + { + return 0; + } + + return basicList.size(); + } + + public List findTargetMapSheetFileList(long targetNum, int pageSize) { + return mapSheetMngFileJobCoreService.findTargetMapSheetFileList(targetNum, pageSize); + } + + public MapSheetMngDto.DmlReturn mngHstDataSyncStateUpdate(MapSheetMngDto.MngHstDto UpdateReq) { + return mapSheetMngFileJobCoreService.mngHstDataSyncStateUpdate(UpdateReq); + } + + public MapSheetMngDto.DmlReturn mngDataSave(MapSheetMngDto.MngFileAddReq AddReq) { + return mapSheetMngFileJobCoreService.mngFileSave(AddReq); + } + + + public List getFilesDepthAll(SrchFilesDepthDto srchDto) { + + Path startPath = Paths.get(srchDto.getDirPath()); + int maxDepth = srchDto.getMaxDepth(); + String dirPath = srchDto.getDirPath(); + String targetFileNm = srchDto.getFileNm(); + String extension = srchDto.getExtension(); + String sortType = srchDto.getSortType(); + + int startPos = srchDto.getStartPos(); + int endPos = srchDto.getEndPos(); + int limit = endPos - startPos + 1; + + Set targetExtensions = createExtensionSet(extension); + + List fileDtoList = new ArrayList<>(); + SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + int fileTotCnt = 0; + long fileTotSize = 0; + + try (Stream stream = Files.walk(startPath, maxDepth)) { + + fileDtoList = + stream + .filter(Files::isRegularFile) + .filter( + p -> + extension == null + || extension.equals("") + || extension.equals("*") + || targetExtensions.contains(extractExtension(p))) + .sorted(getFileComparator(sortType)) + .filter( + p -> p.getFileName().toString().contains(targetFileNm) + ) + .skip(startPos) + .limit(limit) + .map( + path -> { + int depth = path.getNameCount(); + + String fileNm = path.getFileName().toString(); + String ext = FilenameUtils.getExtension(fileNm); + String parentFolderNm = path.getParent().getFileName().toString(); + String parentPath = path.getParent().toString(); + String fullPath = path.toAbsolutePath().toString(); + + File file = new File(fullPath); + long fileSize = file.length(); + String lastModified = dttmFormat.format(new Date(file.lastModified())); + + return new FileDto.Basic( + fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); + }) + .collect(Collectors.toList()); + + //fileTotCnt = fileDtoList.size(); + //fileTotSize = fileDtoList.stream().mapToLong(FileDto.Basic::getFileSize).sum(); + + } catch (IOException e) { + System.err.println("파일 I/O 오류 발생: " + e.getMessage()); + } + + return fileDtoList; + } + + + public Set createExtensionSet(String extensionString) { + if (extensionString == null || extensionString.isBlank()) { + return Set.of(); + } + + // "java, class" -> ["java", " class"] -> [".java", ".class"] + return Arrays.stream(extensionString.split(",")) + .map(ext -> ext.trim()) + .filter(ext -> !ext.isEmpty()) + .map(ext -> "." + ext.toLowerCase()) + .collect(Collectors.toSet()); + } + + public String extractExtension(Path path) { + String filename = path.getFileName().toString(); + int lastDotIndex = filename.lastIndexOf('.'); + + // 확장자가 없거나 파일명이 .으로 끝나는 경우 + if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) { + return ""; // 빈 문자열 반환 + } + + // 확장자 추출 및 소문자 변환 + return filename.substring(lastDotIndex).toLowerCase(); + } + + public Comparator getFileComparator(String sortType) { + + // 파일 이름 비교 기본 Comparator (대소문자 무시) + Comparator nameComparator = + Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); + + Comparator dateComparator = + Comparator.comparing( + path -> { + try { + return Files.getLastModifiedTime(path); + } catch (IOException e) { + return FileTime.fromMillis(0); + } + }); + + if ("name desc".equalsIgnoreCase(sortType)) { + return nameComparator.reversed(); + } else if ("date".equalsIgnoreCase(sortType)) { + return dateComparator; + } else if ("date desc".equalsIgnoreCase(sortType)) { + return dateComparator.reversed(); + } else { + return nameComparator; + } + } + +} From bfcaa5e586406df5afa6c46bbb1cf0a1e99e0b2b Mon Sep 17 00:00:00 2001 From: Moon Date: Tue, 16 Dec 2025 09:24:31 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=98=81=EC=83=81=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EC=8B=B1=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamcoback/common/utils/FIleChecker.java | 114 +++++----- .../kamco/cd/kamcoback/config/FileConfig.java | 1 - .../core/MapSheetMngFileJobCoreService.java | 26 +-- .../entity/MapSheetMngFileEntity.java | 5 + .../MapSheetMngFileJobRepository.java | 2 - .../MapSheetMngFileJobRepositoryCustom.java | 5 - .../MapSheetMngFileJobRepositoryImpl.java | 101 ++++----- .../MapSheetMngFileJobApiController.java | 6 +- .../MapSheetMngFileJobController.java | 34 ++- .../scheduler/dto/MapSheetMngDto.java | 7 - .../service/MapSheetMngFileJobService.java | 214 +++++++++--------- 11 files changed, 240 insertions(+), 275 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java index 895e0c98..7eb6b757 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java @@ -2,7 +2,6 @@ package com.kamco.cd.kamcoback.common.utils; import static java.lang.String.CASE_INSENSITIVE_ORDER; -import com.kamco.cd.kamcoback.scheduler.dto.FileDto; import io.swagger.v3.oas.annotations.media.Schema; import java.io.BufferedReader; import java.io.File; @@ -162,7 +161,7 @@ public class FIleChecker { // 윈도우용 command.add("cmd.exe"); // 윈도우 명령 프롬프트 실행 - command.add("/c"); // 명령어를 수행하고 종료한다는 옵션 + command.add("/c"); // 명령어를 수행하고 종료한다는 옵션 command.add("gdalinfo"); command.add(filePath); command.add("|"); @@ -207,7 +206,6 @@ public class FIleChecker { return hasDriver; } - @Schema(name = "File Basic", description = "파일 기본 정보") @Getter public static class Basic { @@ -221,13 +219,13 @@ public class FIleChecker { private final String lastModified; public Basic( - String fileNm, - String parentFolderNm, - String parentPath, - String fullPath, - String extension, - long fileSize, - String lastModified) { + String fileNm, + String parentFolderNm, + String parentPath, + String fullPath, + String extension, + long fileSize, + String lastModified) { this.fileNm = fileNm; this.parentFolderNm = parentFolderNm; this.parentPath = parentPath; @@ -238,9 +236,14 @@ public class FIleChecker { } } - - - public static List getFilesFromAllDepth(String dir, String targetFileNm, String extension, int maxDepth, String sortType, int startPos, int limit) { + public static List getFilesFromAllDepth( + String dir, + String targetFileNm, + String extension, + int maxDepth, + String sortType, + int startPos, + int limit) { Path startPath = Paths.get(dir); String dirPath = dir; @@ -256,39 +259,36 @@ public class FIleChecker { try (Stream stream = Files.walk(startPath, maxDepth)) { fileList = - stream - .filter(Files::isRegularFile) - .filter( - p -> - extension == null - || extension.equals("") - || extension.equals("*") - || targetExtensions.contains(extractExtension(p))) - .sorted(getFileComparator(sortType)) - .filter( - p -> p.getFileName().toString().contains(targetFileNm) - ) - .skip(startPos) - .limit(limit) - .map( - path -> { - //int depth = path.getNameCount(); + stream + .filter(Files::isRegularFile) + .filter( + p -> + extension == null + || extension.equals("") + || extension.equals("*") + || targetExtensions.contains(extractExtension(p))) + .sorted(getFileComparator(sortType)) + .filter(p -> p.getFileName().toString().contains(targetFileNm)) + .skip(startPos) + .limit(limit) + .map( + path -> { + // int depth = path.getNameCount(); - String fileNm = path.getFileName().toString(); - String ext = FilenameUtils.getExtension(fileNm); - String parentFolderNm = path.getParent().getFileName().toString(); - String parentPath = path.getParent().toString(); - String fullPath = path.toAbsolutePath().toString(); + String fileNm = path.getFileName().toString(); + String ext = FilenameUtils.getExtension(fileNm); + String parentFolderNm = path.getParent().getFileName().toString(); + String parentPath = path.getParent().toString(); + String fullPath = path.toAbsolutePath().toString(); - File file = new File(fullPath); - long fileSize = file.length(); - String lastModified = dttmFormat.format(new Date(file.lastModified())); - - return new Basic( - fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); - }) - .collect(Collectors.toList()); + File file = new File(fullPath); + long fileSize = file.length(); + String lastModified = dttmFormat.format(new Date(file.lastModified())); + return new Basic( + fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); + }) + .collect(Collectors.toList()); } catch (IOException e) { System.err.println("파일 I/O 오류 발생: " + e.getMessage()); @@ -297,7 +297,6 @@ public class FIleChecker { return fileList; } - public static Set createExtensionSet(String extensionString) { if (extensionString == null || extensionString.isBlank()) { return Set.of(); @@ -305,10 +304,10 @@ public class FIleChecker { // "java, class" -> ["java", " class"] -> [".java", ".class"] return Arrays.stream(extensionString.split(",")) - .map(ext -> ext.trim()) - .filter(ext -> !ext.isEmpty()) - .map(ext -> "." + ext.toLowerCase()) - .collect(Collectors.toSet()); + .map(ext -> ext.trim()) + .filter(ext -> !ext.isEmpty()) + .map(ext -> "." + ext.toLowerCase()) + .collect(Collectors.toSet()); } public static String extractExtension(Path path) { @@ -328,17 +327,17 @@ public class FIleChecker { // 파일 이름 비교 기본 Comparator (대소문자 무시) Comparator nameComparator = - Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); + Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); Comparator dateComparator = - Comparator.comparing( - path -> { - try { - return Files.getLastModifiedTime(path); - } catch (IOException e) { - return FileTime.fromMillis(0); - } - }); + Comparator.comparing( + path -> { + try { + return Files.getLastModifiedTime(path); + } catch (IOException e) { + return FileTime.fromMillis(0); + } + }); if ("name desc".equalsIgnoreCase(sortType)) { return nameComparator.reversed(); @@ -350,5 +349,4 @@ public class FIleChecker { return nameComparator; } } - } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java index a7c1ecb0..d401940d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java @@ -15,5 +15,4 @@ public class FileConfig { private String rootSyncDir = "D:\\app\\original-images"; // private String rootSyncDir = "/app/original-images"; - } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java index 88dd2740..8d1dbf03 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngFileJobCoreService.java @@ -1,25 +1,12 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngFileEntity; +import com.kamco.cd.kamcoback.postgres.repository.scheduler.MapSheetMngFileJobRepository; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; -import com.kamco.cd.kamcoback.postgres.repository.scheduler.MapSheetMngFileJobRepository; -import jakarta.persistence.EntityNotFoundException; import jakarta.validation.Valid; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; @@ -30,7 +17,7 @@ public class MapSheetMngFileJobCoreService { private final MapSheetMngFileJobRepository mapSheetMngFileJobRepository; public Page findMapSheetMngList( - MapSheetMngDto.@Valid MngSearchReq searchReq) { + MapSheetMngDto.@Valid MngSearchReq searchReq) { return mapSheetMngFileJobRepository.findMapSheetMngList(searchReq); } @@ -38,14 +25,14 @@ public class MapSheetMngFileJobCoreService { return mapSheetMngFileJobRepository.findTargetMapSheetFileList(targetNum, pageSize); } - public MapSheetMngDto.DmlReturn mngHstDataSyncStateUpdate(@Valid MapSheetMngDto.MngHstDto updateReq) { + public MapSheetMngDto.DmlReturn mngHstDataSyncStateUpdate( + @Valid MapSheetMngDto.MngHstDto updateReq) { mapSheetMngFileJobRepository.mngHstDataSyncStateUpdate(updateReq); - return new MapSheetMngDto.DmlReturn("success", updateReq.getHstUid()+""); + return new MapSheetMngDto.DmlReturn("success", updateReq.getHstUid() + ""); } - public MapSheetMngDto.DmlReturn mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) { MapSheetMngFileEntity entity = new MapSheetMngFileEntity(); @@ -60,9 +47,8 @@ public class MapSheetMngFileJobCoreService { entity.setFileState(addReq.getFileState()); MapSheetMngFileEntity saved = mapSheetMngFileJobRepository.save(entity); - //int hstCnt = mapSheetMngRepository.insertMapSheetOrgDataToMapSheetMngHst(saved.getMngYyyy()); + // int hstCnt = mapSheetMngRepository.insertMapSheetOrgDataToMapSheetMngHst(saved.getMngYyyy()); return new MapSheetMngDto.DmlReturn("success", saved.getFileUid().toString()); } - } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java index 0f81f5c5..83fb9e17 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java @@ -50,4 +50,9 @@ public class MapSheetMngFileEntity { @Column(name = "file_size") private Long fileSize; + + @Size(max = 20) + @Column(name = "file_state", length = 20) + private String fileState; + } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java index 7ffffc8d..9a5ba3e3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepository.java @@ -1,8 +1,6 @@ package com.kamco.cd.kamcoback.postgres.repository.scheduler; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngFileEntity; -import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface MapSheetMngFileJobRepository diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java index 45988ed3..5b10eaee 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryCustom.java @@ -2,10 +2,7 @@ package com.kamco.cd.kamcoback.postgres.repository.scheduler; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; -import jakarta.validation.Valid; import java.util.List; -import java.util.Optional; import org.springframework.data.domain.Page; public interface MapSheetMngFileJobRepositoryCustom { @@ -15,6 +12,4 @@ public interface MapSheetMngFileJobRepositoryCustom { void mngHstDataSyncStateUpdate(MapSheetMngDto.MngHstDto updateReq); List findTargetMapSheetFileList(long targetNum, int pageSize); - - } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java index 689ac10d..d160475e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scheduler/MapSheetMngFileJobRepositoryImpl.java @@ -106,72 +106,63 @@ public class MapSheetMngFileJobRepositoryImpl extends QuerydslRepositorySupport return new PageImpl<>(foundContent, pageable, countQuery); } - public void mngHstDataSyncStateUpdate(MapSheetMngDto.MngHstDto updateReq) { - if( updateReq.getSyncState().equals("DONE") ) { + if (updateReq.getSyncState().equals("DONE")) { long updateCount = - queryFactory - .update(mapSheetMngHstEntity) - .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) - .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) - .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) - .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) - .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) - .execute(); - } - else { + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) + .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) + .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) + .execute(); + } else { long updateCount = - queryFactory - .update(mapSheetMngHstEntity) - .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) - .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) - .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) - .set(mapSheetMngHstEntity.syncStrtDttm, ZonedDateTime.now()) - .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) - .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) - .execute(); + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.dataState, updateReq.getDataState()) + .set(mapSheetMngHstEntity.dataStateDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncState, updateReq.getSyncState()) + .set(mapSheetMngHstEntity.syncStrtDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updateReq.getHstUid())) + .execute(); } - } - @Override - public List findTargetMapSheetFileList(long targetNum, int pageSize) - { - //Pageable pageable = searchReq.toPageable(); + public List findTargetMapSheetFileList(long targetNum, int pageSize) { + // Pageable pageable = searchReq.toPageable(); List foundContent = - queryFactory - .select( - Projections.constructor( - MngHstDto.class, - mapSheetMngHstEntity.hstUid, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mapSheetNum, - mapSheetMngHstEntity.refMapSheetNum, - mapSheetMngHstEntity.dataState, - mapSheetMngHstEntity.syncState, - mapSheetMngHstEntity.syncCheckState, - mapSheetMngHstEntity.syncStrtDttm, - mapSheetMngHstEntity.syncEndDttm, - mapSheetMngHstEntity.syncCheckStrtDttm, - mapSheetMngHstEntity.syncCheckEndDttm, - - mapSheetMngEntity.mngPath - )) - .from(mapSheetMngHstEntity) - .join(mapSheetMngEntity).on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) - .where( - mapSheetMngHstEntity.syncState.eq("NOTYET"), - mapSheetMngHstEntity.hstUid.mod(10L).eq(targetNum) - ).limit(pageSize) - .orderBy(mapSheetMngHstEntity.hstUid.asc()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MngHstDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + mapSheetMngHstEntity.dataState, + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncStrtDttm, + mapSheetMngHstEntity.syncEndDttm, + mapSheetMngHstEntity.syncCheckStrtDttm, + mapSheetMngHstEntity.syncCheckEndDttm, + mapSheetMngEntity.mngPath)) + .from(mapSheetMngHstEntity) + .join(mapSheetMngEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where( + mapSheetMngHstEntity.syncState.eq("NOTYET"), + mapSheetMngHstEntity.hstUid.mod(10L).eq(targetNum)) + .limit(pageSize) + .orderBy(mapSheetMngHstEntity.hstUid.asc()) + .fetch(); return foundContent; } - - - } diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java index 190d2420..5865726a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobApiController.java @@ -11,7 +11,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -40,14 +39,11 @@ public class MapSheetMngFileJobApiController { }) @PutMapping("/mng-sync-job") public ApiResponseDto mngSyncOnOff( - @RequestParam boolean jobStart, - @RequestParam int pageSize) { + @RequestParam boolean jobStart, @RequestParam int pageSize) { mapSheetMngFileJobController.setSchedulerEnabled(jobStart); mapSheetMngFileJobController.setMngSyncPageSize(pageSize); return ApiResponseDto.createOK("OK"); } - - } diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java index e5152fa4..2c6110e7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/MapSheetMngFileJobController.java @@ -13,15 +13,13 @@ public class MapSheetMngFileJobController { private final MapSheetMngFileJobService mapSheetMngFileJobService; // 현재 상태 확인용 Getter - @Getter - private boolean isSchedulerEnabled = false; - @Getter - private int mngSyncPageSize = 20; + @Getter private boolean isSchedulerEnabled = false; + @Getter private int mngSyncPageSize = 20; // 매일 새벽 3시에 실행 (초 분 시 일 월 요일) @Scheduled(fixedDelay = 5000) public void mngFileSyncJob00() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob00 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(0, mngSyncPageSize); @@ -29,7 +27,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob01() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob01 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(1, mngSyncPageSize); @@ -37,7 +35,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob02() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob00 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(2, mngSyncPageSize); @@ -45,7 +43,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob03() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob03 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(3, mngSyncPageSize); @@ -53,7 +51,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob04() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob04 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(4, mngSyncPageSize); @@ -61,7 +59,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob05() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob05 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(5, mngSyncPageSize); @@ -69,7 +67,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob06() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob06 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(6, mngSyncPageSize); @@ -77,7 +75,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob07() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob07 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(7, mngSyncPageSize); @@ -85,7 +83,7 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob08() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob08 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(8, mngSyncPageSize); @@ -93,24 +91,20 @@ public class MapSheetMngFileJobController { @Scheduled(fixedDelay = 5000) public void mngFileSyncJob09() { - if( !isSchedulerEnabled ) return; + if (!isSchedulerEnabled) return; System.out.println("mngFileSyncJob09 === " + System.currentTimeMillis()); mapSheetMngFileJobService.checkMapSheetFileProcess(9, mngSyncPageSize); } - - // 3. 외부에서 플래그를 변경할 수 있는 Setter 메서드 public void setSchedulerEnabled(boolean enabled) { this.isSchedulerEnabled = enabled; - System.out.println("스케줄러 상태 변경됨: "+( enabled ? "ON" : "OFF")); + System.out.println("스케줄러 상태 변경됨: " + (enabled ? "ON" : "OFF")); } public void setMngSyncPageSize(int pageSize) { this.mngSyncPageSize = pageSize; - System.out.println("스케줄러 처리 개수 변경됨: "+pageSize); + System.out.println("스케줄러 처리 개수 변경됨: " + pageSize); } - - } diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java index d975b242..03d3296e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/dto/MapSheetMngDto.java @@ -1,7 +1,6 @@ package com.kamco.cd.kamcoback.scheduler.dto; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; -import com.kamco.cd.kamcoback.config.enums.EnumType; import io.swagger.v3.oas.annotations.media.Schema; import java.time.ZonedDateTime; import lombok.AllArgsConstructor; @@ -10,7 +9,6 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; public class MapSheetMngDto { @@ -78,7 +76,6 @@ public class MapSheetMngDto { private String syncMngPath; } - @Schema(name = "MngFileAddReq", description = "영상관리파일 등록 요청") @Getter @Setter @@ -113,9 +110,6 @@ public class MapSheetMngDto { private Long fileSize; } - - - @Schema(name = "DmlReturn", description = "영상관리 DML 수행 후 리턴") @Getter @Setter @@ -125,5 +119,4 @@ public class MapSheetMngDto { private String flag; private String message; } - } diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java index aed59337..83e12be8 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetMngFileJobService.java @@ -2,19 +2,12 @@ package com.kamco.cd.kamcoback.scheduler.service; import static java.lang.String.CASE_INSENSITIVE_ORDER; -import com.kamco.cd.kamcoback.scheduler.dto.FileDto; -import com.kamco.cd.kamcoback.scheduler.dto.FileDto.FilesDto; -import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDepthDto; -import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDto; -import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; -import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngDto; -import com.kamco.cd.kamcoback.postgres.core.MapSheetMngFileJobCoreService; -import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; - - import com.kamco.cd.kamcoback.common.utils.FIleChecker; -import com.kamco.cd.kamcoback.common.utils.NameValidator; -import com.kamco.cd.kamcoback.config.FileConfig; +import com.kamco.cd.kamcoback.postgres.core.MapSheetMngFileJobCoreService; +import com.kamco.cd.kamcoback.scheduler.dto.FileDto; +import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDepthDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -34,7 +27,6 @@ import lombok.RequiredArgsConstructor; import org.apache.commons.io.FilenameUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; @Service @RequiredArgsConstructor @@ -59,45 +51,56 @@ public class MapSheetMngFileJobService { for (MngHstDto item : mapSheetFileNotYetList) { - //도엽별 파일 체크 진행중으로 변경 + // 도엽별 파일 체크 진행중으로 변경 item.setDataState("PROCESSING"); mngHstDataSyncStateUpdate(item); // 1. MngHstDto 객체의 필드 값에 접근 - //hstUid = item.getHstUid(); - //syncState = item.getSyncState(); + // hstUid = item.getHstUid(); + // syncState = item.getSyncState(); srchDto.setMaxDepth(10); srchDto.setDirPath(item.getSyncMngPath()); srchDto.setExtension("tif,tfw"); srchDto.setFileNm(item.getMapSheetNum()); - //srchDto.setFileNm("34602047"); + // srchDto.setFileNm("34602047"); - System.out.println("UID: " + hstUid + ", 상태: " + syncState + ", 관리경로: " + item.getSyncMngPath() + ", 파일명 " + item.getMapSheetNum() + " .tif,tfw"); + System.out.println( + "UID: " + + hstUid + + ", 상태: " + + syncState + + ", 관리경로: " + + item.getSyncMngPath() + + ", 파일명 " + + item.getMapSheetNum() + + " .tif,tfw"); - //도엽번호로 파일 찾기 - //basicList = this.getFilesDepthAll(srchDto); - - basicList = FIleChecker.getFilesFromAllDepth(srchDto.getDirPath(), srchDto.getFileNm(), - srchDto.getExtension(), srchDto.getMaxDepth(), srchDto.getSortType(), 0, 100); + // 도엽번호로 파일 찾기 + // basicList = this.getFilesDepthAll(srchDto); + basicList = + FIleChecker.getFilesFromAllDepth( + srchDto.getDirPath(), + srchDto.getFileNm(), + srchDto.getExtension(), + srchDto.getMaxDepth(), + srchDto.getSortType(), + 0, + 100); int tfwCnt = - (int) - basicList.stream() - .filter(dto -> dto.getExtension().toString().equals("tfw")) - .count(); + (int) + basicList.stream().filter(dto -> dto.getExtension().toString().equals("tfw")).count(); int tifCnt = - (int) - basicList.stream() - .filter(dto -> dto.getExtension().toString().equals("tif")) - .count(); + (int) + basicList.stream().filter(dto -> dto.getExtension().toString().equals("tif")).count(); syncState = ""; syncCheckState = ""; - if( tfwCnt == 0 && tifCnt == 0)syncState="NOFILE"; + if (tfwCnt == 0 && tifCnt == 0) syncState = "NOFILE"; for (FIleChecker.Basic item2 : basicList) { System.out.println("path: " + item2.getParentPath()); @@ -115,47 +118,59 @@ public class MapSheetMngFileJobService { addReq.setHstUid(item.getHstUid()); fileState = "DONE"; - if(item2.getExtension().equals("tfw") ) { - if( tifCnt == 0){fileState = "NOTPAIR";syncState = fileState;} - else if( tfwCnt > 1){fileState = "DUPLICATE";syncState = fileState;} - else if( item2.getFileSize() == 0 ){fileState = "SIZEERROR";syncState = fileState;} - else if( ! FIleChecker.checkTfw(item2.getFullPath()) ){fileState = "TYPEERROR";syncState = fileState;} - } - else if(item2.getExtension().equals("tif") ){ - if( tfwCnt == 0){fileState = "NOTPAIR";syncState = fileState;} - else if( tifCnt > 1){fileState = "DUPLICATE";syncState = fileState;} - else if( item2.getFileSize() == 0 ){fileState = "SIZEERROR";syncState = fileState;} - else if( ! FIleChecker.cmmndGdalInfo(item2.getFullPath()) ){fileState = "TYPEERROR";syncState = fileState;} + if (item2.getExtension().equals("tfw")) { + if (tifCnt == 0) { + fileState = "NOTPAIR"; + syncState = fileState; + } else if (tfwCnt > 1) { + fileState = "DUPLICATE"; + syncState = fileState; + } else if (item2.getFileSize() == 0) { + fileState = "SIZEERROR"; + syncState = fileState; + } else if (!FIleChecker.checkTfw(item2.getFullPath())) { + fileState = "TYPEERROR"; + syncState = fileState; + } + } else if (item2.getExtension().equals("tif")) { + if (tfwCnt == 0) { + fileState = "NOTPAIR"; + syncState = fileState; + } else if (tifCnt > 1) { + fileState = "DUPLICATE"; + syncState = fileState; + } else if (item2.getFileSize() == 0) { + fileState = "SIZEERROR"; + syncState = fileState; + } else if (!FIleChecker.cmmndGdalInfo(item2.getFullPath())) { + fileState = "TYPEERROR"; + syncState = fileState; + } } addReq.setFileState(fileState); MapSheetMngDto.DmlReturn DmlReturn = mngDataSave(addReq); - } - //도엽별 파일 체크 완료로 변경 + // 도엽별 파일 체크 완료로 변경 item.setDataState("DONE"); - if(syncState.isEmpty())syncState="DONE"; + if (syncState.isEmpty()) syncState = "DONE"; item.setSyncState(syncState); mngHstDataSyncStateUpdate(item); - //srchDto. + // srchDto. // 2. 출력 - //System.out.println("UID: " + hstUid + ", 상태: " + syncState + ", 관리경로: " + item.getSyncMngPath()); + // System.out.println("UID: " + hstUid + ", 상태: " + syncState + ", 관리경로: " + + // item.getSyncMngPath()); // 3. (필요하다면) 다른 로직 수행 // ... } - - - } - public int checkIsNoFile(List basicList) - { - if( basicList == null || basicList.size() == 0 ) - { + public int checkIsNoFile(List basicList) { + if (basicList == null || basicList.size() == 0) { return 0; } @@ -174,7 +189,6 @@ public class MapSheetMngFileJobService { return mapSheetMngFileJobCoreService.mngFileSave(AddReq); } - public List getFilesDepthAll(SrchFilesDepthDto srchDto) { Path startPath = Paths.get(srchDto.getDirPath()); @@ -199,41 +213,39 @@ public class MapSheetMngFileJobService { try (Stream stream = Files.walk(startPath, maxDepth)) { fileDtoList = - stream - .filter(Files::isRegularFile) - .filter( - p -> - extension == null - || extension.equals("") - || extension.equals("*") - || targetExtensions.contains(extractExtension(p))) - .sorted(getFileComparator(sortType)) - .filter( - p -> p.getFileName().toString().contains(targetFileNm) - ) - .skip(startPos) - .limit(limit) - .map( - path -> { - int depth = path.getNameCount(); + stream + .filter(Files::isRegularFile) + .filter( + p -> + extension == null + || extension.equals("") + || extension.equals("*") + || targetExtensions.contains(extractExtension(p))) + .sorted(getFileComparator(sortType)) + .filter(p -> p.getFileName().toString().contains(targetFileNm)) + .skip(startPos) + .limit(limit) + .map( + path -> { + int depth = path.getNameCount(); - String fileNm = path.getFileName().toString(); - String ext = FilenameUtils.getExtension(fileNm); - String parentFolderNm = path.getParent().getFileName().toString(); - String parentPath = path.getParent().toString(); - String fullPath = path.toAbsolutePath().toString(); + String fileNm = path.getFileName().toString(); + String ext = FilenameUtils.getExtension(fileNm); + String parentFolderNm = path.getParent().getFileName().toString(); + String parentPath = path.getParent().toString(); + String fullPath = path.toAbsolutePath().toString(); - File file = new File(fullPath); - long fileSize = file.length(); - String lastModified = dttmFormat.format(new Date(file.lastModified())); + File file = new File(fullPath); + long fileSize = file.length(); + String lastModified = dttmFormat.format(new Date(file.lastModified())); - return new FileDto.Basic( - fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); - }) - .collect(Collectors.toList()); + return new FileDto.Basic( + fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); + }) + .collect(Collectors.toList()); - //fileTotCnt = fileDtoList.size(); - //fileTotSize = fileDtoList.stream().mapToLong(FileDto.Basic::getFileSize).sum(); + // fileTotCnt = fileDtoList.size(); + // fileTotSize = fileDtoList.stream().mapToLong(FileDto.Basic::getFileSize).sum(); } catch (IOException e) { System.err.println("파일 I/O 오류 발생: " + e.getMessage()); @@ -242,7 +254,6 @@ public class MapSheetMngFileJobService { return fileDtoList; } - public Set createExtensionSet(String extensionString) { if (extensionString == null || extensionString.isBlank()) { return Set.of(); @@ -250,10 +261,10 @@ public class MapSheetMngFileJobService { // "java, class" -> ["java", " class"] -> [".java", ".class"] return Arrays.stream(extensionString.split(",")) - .map(ext -> ext.trim()) - .filter(ext -> !ext.isEmpty()) - .map(ext -> "." + ext.toLowerCase()) - .collect(Collectors.toSet()); + .map(ext -> ext.trim()) + .filter(ext -> !ext.isEmpty()) + .map(ext -> "." + ext.toLowerCase()) + .collect(Collectors.toSet()); } public String extractExtension(Path path) { @@ -273,17 +284,17 @@ public class MapSheetMngFileJobService { // 파일 이름 비교 기본 Comparator (대소문자 무시) Comparator nameComparator = - Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); + Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); Comparator dateComparator = - Comparator.comparing( - path -> { - try { - return Files.getLastModifiedTime(path); - } catch (IOException e) { - return FileTime.fromMillis(0); - } - }); + Comparator.comparing( + path -> { + try { + return Files.getLastModifiedTime(path); + } catch (IOException e) { + return FileTime.fromMillis(0); + } + }); if ("name desc".equalsIgnoreCase(sortType)) { return nameComparator.reversed(); @@ -295,5 +306,4 @@ public class MapSheetMngFileJobService { return nameComparator; } } - } From b6a96846b56e67f44d7b5f678354af7977f6773e Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 16 Dec 2025 11:27:08 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=ED=8C=A8=EC=8A=A4=EC=9B=8C=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EC=85=8B=20=EB=8D=B0=EC=9D=B4=ED=84=B0=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B3=80=EA=B2=BD,=20spotlessApply=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/postgres/core/MembersCoreService.java | 4 ++-- .../kamcoback/postgres/entity/MapSheetMngFileEntity.java | 1 - .../kamco/cd/kamcoback/postgres/entity/MemberEntity.java | 7 ++----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java index 4bb2aba7..b59f71fc 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java @@ -90,7 +90,7 @@ public class MembersCoreService { memberEntity.setStatus(StatusType.PENDING.getId()); memberEntity.setLoginFailCount(0); memberEntity.setPassword(password); - memberEntity.setPwdResetYn("Y"); + memberEntity.setPwdResetYn(true); } memberEntity.setUpdtrUid(userUtil.getId()); membersRepository.save(memberEntity); @@ -117,7 +117,7 @@ public class MembersCoreService { memberEntity.setStatus(StatusType.ACTIVE.getId()); memberEntity.setUpdatedDttm(ZonedDateTime.now()); memberEntity.setUpdtrUid(memberEntity.getId()); - memberEntity.setPwdResetYn("N"); + memberEntity.setPwdResetYn(false); membersRepository.save(memberEntity); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java index 83fb9e17..70542b4f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngFileEntity.java @@ -54,5 +54,4 @@ public class MapSheetMngFileEntity { @Size(max = 20) @Column(name = "file_state", length = 20) private String fileState; - } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java index 6ada3332..d2088ad9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java @@ -9,14 +9,12 @@ import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.sql.Types; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.ColumnDefault; -import org.hibernate.annotations.JdbcTypeCode; @Getter @Setter @@ -91,9 +89,8 @@ public class MemberEntity { @Column(name = "status_chg_dttm") private ZonedDateTime statusChgDttm; - @JdbcTypeCode(Types.CHAR) - @Column(name = "pwd_reset_yn", columnDefinition = "CHAR(1)") - private String pwdResetYn; + @Column(name = "pwd_reset_yn") + private Boolean pwdResetYn; public void changeStatus(String newStatus) { // 같은 값 보내도 무시