Redis Cache Status Error Fix

This commit is contained in:
DanielLee
2025-12-09 09:32:33 +09:00
parent df9649fb1b
commit c3245ab79c
24 changed files with 605 additions and 688 deletions

View File

@@ -13,8 +13,7 @@ import org.springframework.stereotype.Component;
/**
* 공통코드 캐시 관리 및 초기화 클래스
*
* <p>애플리케이션 시작 시 공통코드를 Redis 캐시에 미리 로드하고, 캐시 갱신을 관리합니다.
* 기존 Redis 데이터와의 호환성 문제로 인한 간헐적 오류를 방지합니다.
* <p>애플리케이션 시작 시 공통코드를 Redis 캐시에 미리 로드하고, 캐시 갱신을 관리합니다. 기존 Redis 데이터와의 호환성 문제로 인한 간헐적 오류를 방지합니다.
*/
@Slf4j
@Component
@@ -29,9 +28,8 @@ public class CommonCodeCacheManager {
/**
* 애플리케이션 시작 완료 후 공통코드를 Redis 캐시에 미리 로드
*
* <p>이 메서드는 Spring 애플리케이션이 완전히 시작된 후에 자동으로 실행되며, 공통코드 데이터를 Redis
* 캐시에 미리 로드하여 초기 조회 시 성능을 최적화합니다. 기존 캐시 데이터 호환성 문제를 대비하여 먼저
* 캐시를 초기화한 후 재로드합니다.
* <p>이 메서드는 Spring 애플리케이션이 완전히 시작된 후에 자동으로 실행되며, 공통코드 데이터를 Redis 캐시에 미리 로드하여 초기 조회 시 성능을 최적화합니다.
* 기존 캐시 데이터 호환성 문제를 대비하여 먼저 캐시를 초기화한 후 재로드합니다.
*/
@EventListener(ApplicationReadyEvent.class)
public void initializeCommonCodeCache() {
@@ -48,27 +46,18 @@ public class CommonCodeCacheManager {
// 2. DB에서 새로운 데이터 로드 (캐시 미스 상태)
List<Basic> allCommonCodes = commonCodeService.getFindAll();
log.info(
"✓ 공통코드 {}개를 DB에서 로드하고 Redis 캐시에 저장했습니다.",
allCommonCodes.size());
log.info("✓ 공통코드 {}개를 DB에서 로드하고 Redis 캐시에 저장했습니다.", allCommonCodes.size());
// 3. 로그 출력 (DEBUG 레벨)
if (log.isDebugEnabled()) {
allCommonCodes.forEach(
code ->
log.debug(
" - [{}] {} (ID: {})",
code.getCode(),
code.getName(),
code.getId()));
code ->
log.debug(" - [{}] {} (ID: {})", code.getCode(), code.getName(), code.getId()));
}
log.info("=== 공통코드 캐시 초기화 완료 ===");
} catch (Exception e) {
log.warn(
"공통코드 캐시 초기화 중 오류 발생했습니다. 캐시 없이 계속 진행합니다. "
+ "(첫 번째 조회 시 DB에서 로드되고 캐시됩니다.)",
e);
log.warn("공통코드 캐시 초기화 중 오류 발생했습니다. 캐시 없이 계속 진행합니다. " + "(첫 번째 조회 시 DB에서 로드되고 캐시됩니다.)", e);
}
}
@@ -121,10 +110,31 @@ public class CommonCodeCacheManager {
*/
public int getCachedCommonCodeCount() {
try {
List<Basic> cachedCodes = commonCodeService.getFindAll();
return cachedCodes.size();
// 캐시 오류 시 자동으로 재초기화
try {
List<Basic> cachedCodes = commonCodeService.getFindAll();
return cachedCodes.size();
} catch (Exception cacheError) {
log.debug("캐시 조회 중 호환성 오류 감지, 캐시 재초기화 중...: {}", cacheError.getMessage());
// 기존 호환성 문제가 있는 캐시 데이터 강제 제거
try {
var cache = cacheManager.getCache(COMMON_CODES_CACHE_NAME);
if (cache != null) {
cache.clear();
log.debug("✓ 호환되지 않는 캐시 데이터 제거 완료");
}
} catch (Exception clearEx) {
log.debug("캐시 정리 중 예외: {}", clearEx.getMessage());
}
// 재시도
List<Basic> cachedCodes = commonCodeService.getFindAll();
log.info("✓ 캐시 재초기화 완료, 공통코드 {}개 로드됨", cachedCodes.size());
return cachedCodes.size();
}
} catch (Exception e) {
log.warn("캐시 상태 확인 중 오류 발생: {}", e.getMessage());
log.warn("캐시 상태 확인 중 최종 오류 발생: {}", e.getMessage());
return 0;
}
}

View File

@@ -13,8 +13,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.gce.geotiff.GeoTiffReader;
@@ -47,9 +45,8 @@ public class FIleChecker {
return true;
}
public static boolean verifyFileIntegrity(Path path, String expectedHash)
throws IOException, NoSuchAlgorithmException {
throws IOException, NoSuchAlgorithmException {
// 1. 알고리즘 선택 (SHA-256 권장, MD5는 보안상 비추천)
MessageDigest digest = MessageDigest.getInstance("SHA-256");
@@ -72,7 +69,6 @@ public class FIleChecker {
return actualHash.equalsIgnoreCase(expectedHash);
}
public static boolean checkTfw(String filePath) {
File file = new File(filePath);
@@ -90,13 +86,13 @@ public class FIleChecker {
lines.add(Double.parseDouble(line.trim()));
}
}
}catch (IOException ignored) {
} catch (IOException ignored) {
return false;
}
// 2. 6줄이 맞는지 확인
if (lines.size() < 6) {
//System.out.println("유효하지 않은 TFW 파일입니다. (데이터 부족)");
// System.out.println("유효하지 않은 TFW 파일입니다. (데이터 부족)");
return false;
}
@@ -123,9 +119,9 @@ public class FIleChecker {
if (coverage == null) return false;
// 3. GIS 필수 정보(좌표계)가 있는지 확인
//if (coverage.getCoordinateReferenceSystem() == null) {
// GeoTIFF가 아니라 일반 TIFF일 수도 있음(이미지는 정상이지만, 좌표계(CRS) 정보가 없습니다.)
//}
// if (coverage.getCoordinateReferenceSystem() == null) {
// GeoTIFF가 아니라 일반 TIFF일 수도 있음(이미지는 정상이지만, 좌표계(CRS) 정보가 없습니다.)
// }
return true;
@@ -149,59 +145,57 @@ public class FIleChecker {
String resStr = "";
boolean hasDriver = false;
// 리눅스/맥용
//ProcessBuilder pb = new ProcessBuilder("sh", "-c", "gdalinfo "+filePath+" | grep -i 'Geo'");
// 리눅스/맥용
// ProcessBuilder pb = new ProcessBuilder("sh", "-c", "gdalinfo "+filePath+" | grep -i 'Geo'");
List<String> command = new ArrayList<>();
List<String> command = new ArrayList<>();
//윈도우용
command.add("cmd.exe"); // 윈도우 명령 프롬프트 실행
command.add("/c"); // 명령어를 수행하고 종료한다는 옵션
//command.add("C:\\Program Files\\QGIS 3.44.4\\bin\\gdalinfo");
command.add("gdalinfo");
command.add(filePath);
command.add("|");
command.add("findstr");
command.add("/i");
command.add("Geo");
// 윈도우용
command.add("cmd.exe"); // 윈도우 명령 프롬프트 실행
command.add("/c"); // 명령어를 수행하고 종료한다는 옵션
// command.add("C:\\Program Files\\QGIS 3.44.4\\bin\\gdalinfo");
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");
*/
/*
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);
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
try {
Process process = processBuilder.start();
// 인코딩은 윈도우 한글 환경에 맞게 MS949로 지정
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
// 인코딩은 윈도우 한글 환경에 맞게 MS949로 지정
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
//System.out.println(line);
if( line.contains("Driver: GTiff/GeoTIFF")) {
hasDriver = true;
break;
}
String line;
while ((line = reader.readLine()) != null) {
// System.out.println(line);
if (line.contains("Driver: GTiff/GeoTIFF")) {
hasDriver = true;
break;
}
int exitCode = process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
int exitCode = process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return hasDriver;
}
}

View File

@@ -45,198 +45,197 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(EntityNotFoundException.class)
public ApiResponseDto<String> handlerEntityNotFoundException(
EntityNotFoundException e, HttpServletRequest request) {
EntityNotFoundException e, HttpServletRequest request) {
log.warn("[EntityNotFoundException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_DATA";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public ApiResponseDto<String> handleUnreadable(
HttpMessageNotReadableException e, HttpServletRequest request) {
HttpMessageNotReadableException e, HttpServletRequest request) {
log.warn("[HttpMessageNotReadableException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoSuchElementException.class)
public ApiResponseDto<String> handlerNoSuchElementException(
NoSuchElementException e, HttpServletRequest request) {
NoSuchElementException e, HttpServletRequest request) {
log.warn("[NoSuchElementException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_DATA";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("NOT_FOUND"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("NOT_FOUND"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ApiResponseDto<String> handlerIllegalArgumentException(
IllegalArgumentException e, HttpServletRequest request) {
IllegalArgumentException e, HttpServletRequest request) {
log.warn("[handlerIllegalArgumentException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(DataIntegrityViolationException.class)
public ApiResponseDto<String> handlerDataIntegrityViolationException(
DataIntegrityViolationException e, HttpServletRequest request) {
DataIntegrityViolationException e, HttpServletRequest request) {
log.warn("[DataIntegrityViolationException] resource :{} ", e.getMessage());
String codeName = "DATA_INTEGRITY_ERROR";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResponseDto<String> handlerMethodArgumentNotValidException(
MethodArgumentNotValidException e, HttpServletRequest request) {
MethodArgumentNotValidException e, HttpServletRequest request) {
log.warn("[MethodArgumentNotValidException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AccessDeniedException.class)
public ApiResponseDto<String> handlerAccessDeniedException(
AccessDeniedException e, HttpServletRequest request) {
AccessDeniedException e, HttpServletRequest request) {
log.warn("[AccessDeniedException] resource :{} ", e.getMessage());
String codeName = "UNAUTHORIZED";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_GATEWAY)
@ExceptionHandler(HttpServerErrorException.BadGateway.class)
public ApiResponseDto<String> handlerHttpServerErrorException(
HttpServerErrorException e, HttpServletRequest request) {
HttpServerErrorException e, HttpServletRequest request) {
log.warn("[HttpServerErrorException] resource :{} ", e.getMessage());
String codeName = "BAD_GATEWAY";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(IllegalStateException.class)
public ApiResponseDto<String> handlerIllegalStateException(
IllegalStateException e, HttpServletRequest request) {
IllegalStateException e, HttpServletRequest request) {
log.warn("[IllegalStateException] resource :{} ", e.getMessage());
String codeName = "UNPROCESSABLE_ENTITY";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MemberException.DuplicateMemberException.class)
public ApiResponseDto<String> handlerDuplicateMemberException(
MemberException.DuplicateMemberException e, HttpServletRequest request) {
MemberException.DuplicateMemberException e, HttpServletRequest request) {
log.warn("[DuplicateMemberException] resource :{} ", e.getMessage());
String codeName = "";
@@ -254,115 +253,112 @@ public class GlobalExceptionHandler {
}
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MemberException.MemberNotFoundException.class)
public ApiResponseDto<String> handlerMemberNotFoundException(
MemberException.MemberNotFoundException e, HttpServletRequest request) {
MemberException.MemberNotFoundException e, HttpServletRequest request) {
log.warn("[MemberNotFoundException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_USER";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(DuplicateKeyException.class)
public ApiResponseDto<String> handlerDuplicateKeyException(
DuplicateKeyException e, HttpServletRequest request) {
DuplicateKeyException e, HttpServletRequest request) {
log.warn("[DuplicateKeyException] resource :{} ", e.getMessage());
String codeName = "DUPLICATE_DATA";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("CONFLICT"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("CONFLICT"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("CONFLICT"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("CONFLICT"),
errorLog.getId());
}
@ExceptionHandler(BadCredentialsException.class)
public ResponseEntity<ApiResponseDto<String>> handleBadCredentials(
BadCredentialsException e, HttpServletRequest request
) {
BadCredentialsException e, HttpServletRequest request) {
log.warn("[BadCredentialsException] resource : {} ", e.getMessage());
String codeName = "UNAUTHORIZED";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
ApiResponseDto<String> body =
ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
return ResponseEntity
.status(HttpStatus.UNAUTHORIZED) // 🔥 여기서 401 지정
.body(body);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED) // 🔥 여기서 401 지정
.body(body);
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class)
public ApiResponseDto<String> handlerRuntimeException(
RuntimeException e, HttpServletRequest request) {
RuntimeException e, HttpServletRequest request) {
log.warn("[RuntimeException] resource :{} ", e.getMessage());
String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@@ -372,36 +368,36 @@ public class GlobalExceptionHandler {
String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
/**
* 에러 로그 테이블 저장 로직
*
* @param request : request
* @param errorCode : 정의된 enum errorCode
* @param httpStatus : HttpStatus 값
* @param request : request
* @param errorCode : 정의된 enum errorCode
* @param httpStatus : HttpStatus 값
* @param logErrorLevel : WARNING, ERROR, CRITICAL
* @param stackTrace : 에러 내용
* @param stackTrace : 에러 내용
* @return : insert하고 결과로 받은 Entity
*/
private ErrorLogEntity saveErrorLogData(
HttpServletRequest request,
ApiResponseCode errorCode,
HttpStatus httpStatus,
ErrorLogDto.LogErrorLevel logErrorLevel,
StackTraceElement[] stackTrace) {
HttpServletRequest request,
ApiResponseCode errorCode,
HttpStatus httpStatus,
ErrorLogDto.LogErrorLevel logErrorLevel,
StackTraceElement[] stackTrace) {
Long userid = null;
@@ -415,35 +411,35 @@ public class GlobalExceptionHandler {
* 만든 CustomUserDetails 타입인가? 체크
*/
if (request.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
// audit 에는 long 타입 user_id가 들어가지만 토큰 sub은 uuid여서 user_id 가져오기
userid = customUserDetails.getMember().getId();
}
String stackTraceStr =
Arrays.stream(stackTrace)
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"))
.substring(0, Math.min(stackTrace.length, 255));
Arrays.stream(stackTrace)
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"))
.substring(0, Math.min(stackTrace.length, 255));
ErrorLogEntity errorLogEntity =
new ErrorLogEntity(
request.getRequestURI(),
ApiLogFunction.getEventType(request),
logErrorLevel,
String.valueOf(httpStatus.value()),
errorCode.getText(),
stackTraceStr,
userid,
ZonedDateTime.now());
new ErrorLogEntity(
request.getRequestURI(),
ApiLogFunction.getEventType(request),
logErrorLevel,
String.valueOf(httpStatus.value()),
errorCode.getText(),
stackTraceStr,
userid,
ZonedDateTime.now());
return errorLogRepository.save(errorLogEntity);
}
@ExceptionHandler(CustomApiException.class)
public ResponseEntity<ApiResponseDto<String>> handleCustomApiException(
CustomApiException e, HttpServletRequest request) {
CustomApiException e, HttpServletRequest request) {
log.warn("[CustomApiException] resource : {}", e.getMessage());
String codeName = e.getCodeName();
@@ -453,11 +449,11 @@ public class GlobalExceptionHandler {
ApiResponseCode apiCode = ApiResponseCode.getCode(codeName);
ErrorLogEntity errorLog =
saveErrorLogData(
request, apiCode, status, ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace());
saveErrorLogData(
request, apiCode, status, ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace());
ApiResponseDto<String> body =
ApiResponseDto.createException(apiCode, message, status, errorLog.getId());
ApiResponseDto.createException(apiCode, message, status, errorLog.getId());
return new ResponseEntity<>(body, status);
}

View File

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.Duration;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
@@ -81,15 +82,21 @@ public class RedisConfig {
cacheObjectMapper.registerModule(new JavaTimeModule());
cacheObjectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
cacheObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 알 수 없는 타입에 대해 더 유연하게 처리
cacheObjectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
cacheObjectMapper.findAndRegisterModules();
// 타입 정보 포함 - JAVA_LANG_OBJECT로 제한적으로 적용
// 호환성 문제 해결을 위해 더 많은 타입 허용
PolymorphicTypeValidator ptv =
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.kamco.cd.kamcoback")
.allowIfSubType("org.springframework.data.domain")
.allowIfSubType("java.util")
.allowIfSubType("java.time")
.allowIfSubType("java.lang")
.allowIfBaseType(List.class)
.allowIfBaseType("com.kamco.cd.kamcoback.code.dto.CommonCodeDto$Basic")
.build();
cacheObjectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT);

View File

@@ -29,30 +29,29 @@ public class SecurityConfig {
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
.sessionManagement(
sm ->
sm.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
.authenticationProvider(
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
.authorizeHttpRequests(
auth ->
auth.requestMatchers(
"/api/auth/signin",
"/api/auth/refresh",
"/swagger-ui/**",
"/v3/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
.sessionManagement(
sm ->
sm.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
.authenticationProvider(
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
.authorizeHttpRequests(
auth ->
auth.requestMatchers(
"/api/auth/signin",
"/api/auth/refresh",
"/swagger-ui/**",
"/v3/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
;
return http.build();
@@ -60,7 +59,7 @@ public class SecurityConfig {
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
throws Exception {
throws Exception {
return configuration.getAuthenticationManager();
}

View File

@@ -6,11 +6,8 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@SecurityScheme(
name = "BearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
public class SwaggerConfig {
}
name = "BearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT")
public class SwaggerConfig {}

View File

@@ -64,22 +64,22 @@ public class ApiLogFunction {
}
public static String getRequestBody(
HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) {
HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) {
StringBuilder resultBody = new StringBuilder();
// GET, form-urlencoded POST 파라미터
Map<String, String[]> paramMap = servletRequest.getParameterMap();
String queryParams =
paramMap.entrySet().stream()
.map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
.collect(Collectors.joining("&"));
paramMap.entrySet().stream()
.map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
.collect(Collectors.joining("&"));
resultBody.append(queryParams.isEmpty() ? "" : queryParams);
// JSON Body
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
&& servletRequest.getContentType() != null
&& servletRequest.getContentType().contains("application/json")) {
&& servletRequest.getContentType() != null
&& servletRequest.getContentType().contains("application/json")) {
try {
// json인 경우는 Wrapper를 통해 가져오기
resultBody.append(getBodyData(contentWrapper));
@@ -91,8 +91,8 @@ public class ApiLogFunction {
// Multipart form-data
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
&& servletRequest.getContentType() != null
&& servletRequest.getContentType().startsWith("multipart/form-data")) {
&& servletRequest.getContentType() != null
&& servletRequest.getContentType().startsWith("multipart/form-data")) {
resultBody.append("multipart/form-data request");
}

View File

@@ -31,19 +31,19 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(
MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// ApiResponseDto를 반환하는 경우에만 적용
return returnType.getParameterType().equals(ApiResponseDto.class);
}
@Override
public Object beforeBodyWrite(
Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
ContentCachingRequestWrapper contentWrapper = (ContentCachingRequestWrapper) servletRequest;
@@ -57,15 +57,16 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
Long userid = null;
/**
* servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
* 이 요청이 JWT 인증을 통과한 요청인가? 그리고 Spring Security Authentication 객체가 UsernamePasswordAuthenticationToken 타입인가? 체크
* servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth 이 요청이
* JWT 인증을 통과한 요청인가? 그리고 Spring Security Authentication 객체가
* UsernamePasswordAuthenticationToken 타입인가? 체크
*/
/**
* auth.getPrincipal() instanceof CustomUserDetails customUserDetails
* principal 안에 들어있는 객체가 내가 만든 CustomUserDetails 타입인가? 체크
* auth.getPrincipal() instanceof CustomUserDetails customUserDetails principal 안에 들어있는 객체가 내가
* 만든 CustomUserDetails 타입인가? 체크
*/
if (servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
// audit 에는 long 타입 user_id가 들어가지만 토큰 sub은 uuid여서 user_id 가져오기
userid = customUserDetails.getMember().getId();
@@ -76,15 +77,15 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
// TODO: menuUid 를 동적으로 가져오게끔 해야함
AuditLogEntity log =
new AuditLogEntity(
userid,
ApiLogFunction.getEventType(servletRequest),
ApiLogFunction.isSuccessFail(apiResponse),
"MU_01_01",
ip,
servletRequest.getRequestURI(),
requestBody,
apiResponse.getErrorLogUid());
new AuditLogEntity(
userid,
ApiLogFunction.getEventType(servletRequest),
ApiLogFunction.isSuccessFail(apiResponse),
"MU_01_01",
ip,
servletRequest.getRequestURI(),
requestBody,
apiResponse.getErrorLogUid());
// tb_audit_log 테이블 저장
auditLogRepository.save(log);
}

View File

@@ -3,12 +3,6 @@ package com.kamco.cd.kamcoback.mapsheet;
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 com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDepthDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngService;
import io.swagger.v3.oas.annotations.Operation;
@@ -63,7 +57,6 @@ public class MapSheetMngApiController {
return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngList(searchReq));
}
/**
* @param hstUidList
* @return

View File

@@ -9,9 +9,7 @@ import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDepthDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngFileCheckerService;
import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -19,11 +17,8 @@ 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 jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.PostMapping;
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.RestController;
@@ -93,26 +88,22 @@ public class MapSheetMngFileCheckerApiController {
return ApiResponseDto.createOK(mapSheetMngFileCheckerService.getFilesDepthAll(srchDto));
}
@Operation(summary = "영상데이터관리 > 영상파일 동기화", description = "영상파일 동기화")
@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)
})
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)
})
@PostMapping("/sync-process")
public ApiResponseDto<ImageryDto.SyncReturn> syncProcess(
@RequestBody @Valid ImageryDto.searchReq searchReq) {
@RequestBody @Valid ImageryDto.searchReq searchReq) {
return ApiResponseDto.ok(mapSheetMngFileCheckerService.syncProcess(searchReq));
}
}

View File

@@ -1,8 +1,6 @@
package com.kamco.cd.kamcoback.mapsheet.dto;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
import java.time.ZonedDateTime;
import java.util.UUID;
@@ -10,10 +8,8 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
public class ImageryDto {
@@ -43,7 +39,9 @@ public class ImageryDto {
@NotNull
private Integer mngYyyy;
public Pageable toPageable() {return PageRequest.of(page, size);}
public Pageable toPageable() {
return PageRequest.of(page, size);
}
}
@Schema(name = "ImageryDto", description = "영상관리파일 검색 리턴")
@@ -94,7 +92,4 @@ public class ImageryDto {
private int tfwErrCnt;
private int tifErrCnt;
}
}

View File

@@ -11,7 +11,6 @@ import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDepthDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngFileCheckerCoreService;
import java.io.File;
import java.io.IOException;
@@ -302,9 +301,7 @@ public class MapSheetMngFileCheckerService {
}
}
public ImageryDto.SyncReturn syncProcess(ImageryDto.searchReq searchReq) {
return mapSheetMngFileCheckerCoreService.syncProcess(searchReq);
}
}

View File

@@ -2,15 +2,10 @@ package com.kamco.cd.kamcoback.mapsheet.service;
import static java.lang.String.CASE_INSENSITIVE_ORDER;
import com.kamco.cd.kamcoback.common.utils.NameValidator;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FolderDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDepthDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
import jakarta.validation.Valid;
@@ -42,8 +37,6 @@ public class MapSheetMngService {
private final MapSheetMngCoreService mapSheetMngCoreService;
public FilesDto getFilesAll(SrchFilesDto srchDto) {
String dirPath = srchDto.getDirPath();
@@ -236,7 +229,4 @@ public class MapSheetMngService {
public MapSheetMngDto.DmlReturn updateExceptUseInference(@Valid List<Long> hstUidList) {
return mapSheetMngCoreService.updateExceptUseInference(hstUidList);
}
}

View File

@@ -30,139 +30,138 @@ public class AdminApiController {
@Operation(summary = "회원가입", description = "회원가입")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "회원가입 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "회원가입 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/join")
public ApiResponseDto<Long> saveMember(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "회원가입",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.AddReq.class)))
@RequestBody
@Valid
MembersDto.AddReq addReq) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "회원가입",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.AddReq.class)))
@RequestBody
@Valid
MembersDto.AddReq addReq) {
return ApiResponseDto.createOK(adminService.saveMember(addReq));
}
@Operation(summary = "역할 추가", description = "uuid 기준으로 역할 추가")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "역할 추가",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "역할 추가",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/roles/add")
public ApiResponseDto<UUID> saveRoles(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 추가",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 추가",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
adminService.saveRoles(rolesDto);
return ApiResponseDto.createOK(rolesDto.getUuid());
}
@Operation(summary = "역할 삭제", description = "uuid 기준으로 역할 삭제")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "역할 삭제",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "역할 삭제",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/roles/rm")
public ApiResponseDto<UUID> deleteRoles(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 삭제",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "역할 삭제",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.RolesDto.class)))
@RequestBody
@Valid
MembersDto.RolesDto rolesDto) {
adminService.deleteRoles(rolesDto);
return ApiResponseDto.createOK(rolesDto.getUuid());
}
@Operation(summary = "상태 수정", description = "상태 수정")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "상태 수정",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "상태 수정",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PatchMapping("{uuid}/status")
public ApiResponseDto<UUID> updateStatus(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "상태 수정",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.StatusDto.class)))
@PathVariable UUID uuid,
@RequestBody
@Valid
MembersDto.StatusDto statusDto) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "상태 수정",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.StatusDto.class)))
@PathVariable
UUID uuid,
@RequestBody @Valid MembersDto.StatusDto statusDto) {
adminService.updateStatus(uuid, statusDto);
return ApiResponseDto.createOK(uuid);
}
@Operation(summary = "회원 탈퇴", description = "회원 탈퇴")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "회원 탈퇴",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "회원 탈퇴",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/delete/{uuid}")
public ApiResponseDto<UUID> deleteAccount(@PathVariable UUID uuid) {
adminService.deleteAccount(uuid);
@@ -171,18 +170,18 @@ public class AdminApiController {
@Operation(summary = "비밀번호 초기화", description = "비밀번호 초기화")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "비밀번호 초기화",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "비밀번호 초기화",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PatchMapping("/{memberId}/password")
public ApiResponseDto<Long> resetPassword(@PathVariable Long memberId) {
adminService.resetPassword(memberId);

View File

@@ -47,24 +47,24 @@ public class AuthController {
@Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "로그인 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
responseCode = "200",
description = "로그인 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
@ApiResponse(
responseCode = "401",
description = "ID 또는 비밀번호 불일치",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
responseCode = "401",
description = "ID 또는 비밀번호 불일치",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
public ApiResponseDto<TokenResponse> signin(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "로그인 요청 정보",
required = true)
@RequestBody
SignInRequest request,
HttpServletResponse response) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "로그인 요청 정보",
required = true)
@RequestBody
SignInRequest request,
HttpServletResponse response) {
Authentication authentication =
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
String username = authentication.getName(); // UserDetailsService 에서 사용한 username
@@ -73,17 +73,17 @@ public class AuthController {
// Redis에 RefreshToken 저장 (TTL = 7일)
refreshTokenService.save(
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
// HttpOnly + Secure 쿠키에 RefreshToken 저장
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, refreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, refreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ApiResponseDto.ok(new TokenResponse(accessToken));
@@ -93,15 +93,16 @@ public class AuthController {
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "재발급 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
responseCode = "200",
description = "재발급 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
@ApiResponse(
responseCode = "401",
description = "만료되었거나 유효하지 않은 리프레시 토큰",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
responseCode = "401",
description = "만료되었거나 유효하지 않은 리프레시 토큰",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response) throws AccessDeniedException {
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response)
throws AccessDeniedException {
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
}
@@ -119,17 +120,17 @@ public class AuthController {
// Redis 갱신
refreshTokenService.save(
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
// 쿠키 갱신
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, newRefreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, newRefreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ResponseEntity.ok(new TokenResponse(newAccessToken));
@@ -139,11 +140,12 @@ public class AuthController {
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "로그아웃 성공",
content = @Content(schema = @Schema(implementation = Void.class)))
responseCode = "200",
description = "로그아웃 성공",
content = @Content(schema = @Schema(implementation = Void.class)))
})
public ApiResponseDto<ResponseEntity<Object>> logout(Authentication authentication, HttpServletResponse response) {
public ApiResponseDto<ResponseEntity<Object>> logout(
Authentication authentication, HttpServletResponse response) {
if (authentication != null) {
String username = authentication.getName();
// Redis에서 RefreshToken 삭제
@@ -152,19 +154,17 @@ public class AuthController {
// 쿠키 삭제 (Max-Age=0)
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, "")
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(0)
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, "")
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(0)
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ApiResponseDto.createOK(ResponseEntity.noContent().build());
}
public record TokenResponse(String accessToken) {
}
public record TokenResponse(String accessToken) {}
}

View File

@@ -31,40 +31,40 @@ public class MembersApiController {
@Operation(summary = "회원정보 목록", description = "회원정보 조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "검색 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Page.class))),
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "200",
description = "검색 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Page.class))),
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping
public ApiResponseDto<Page<Basic>> getMemberList(
@ParameterObject MembersDto.SearchReq searchReq) {
@ParameterObject MembersDto.SearchReq searchReq) {
return ApiResponseDto.ok(membersService.findByMembers(searchReq));
}
@Operation(summary = "회원정보 수정", description = "회원정보 수정")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "회원정보 수정",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "회원정보 수정",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PutMapping("/{uuid}")
public ApiResponseDto<UUID> updateMember(
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
membersService.updateMember(uuid, updateReq);
return ApiResponseDto.createOK(uuid);
}

View File

@@ -28,21 +28,19 @@ public class MembersDto {
private String email;
private String status;
private String roleName;
@JsonFormatDttm
private ZonedDateTime createdDttm;
@JsonFormatDttm
private ZonedDateTime updatedDttm;
@JsonFormatDttm private ZonedDateTime createdDttm;
@JsonFormatDttm private ZonedDateTime updatedDttm;
public Basic(
Long id,
UUID uuid,
String employeeNo,
String name,
String email,
String status,
String roleName,
ZonedDateTime createdDttm,
ZonedDateTime updatedDttm) {
Long id,
UUID uuid,
String employeeNo,
String name,
String email,
String status,
String roleName,
ZonedDateTime createdDttm,
ZonedDateTime updatedDttm) {
this.id = id;
this.uuid = uuid;
this.employeeNo = employeeNo;

View File

@@ -1,7 +1,5 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.common.utils.FIleChecker;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
@@ -124,8 +122,4 @@ public class MapSheetMngCoreService {
throw new RuntimeException("File search error", e);
}
}
}

View File

@@ -2,23 +2,7 @@ package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.common.utils.FIleChecker;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngFileCheckerRepository;
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;
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.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;
@@ -35,36 +19,35 @@ public class MapSheetMngFileCheckerCoreService {
@Value("{spring.profiles.active}")
private String activeEnv;
public ImageryDto.SyncReturn syncProcess(ImageryDto.searchReq searchReq) {
String flag = "SUCCESS";
int syncCnt = 0;
int tfwErrCnt = 0;
int tifErrCnt = 0;
//대상파일목록 가저오기
Page<ImageryDto.SyncDto> pageImagerySyncDto = mapSheetMngFileCheckerRepository.findImagerySyncList(searchReq);
// 대상파일목록 가저오기
Page<ImageryDto.SyncDto> pageImagerySyncDto =
mapSheetMngFileCheckerRepository.findImagerySyncList(searchReq);
for (ImageryDto.SyncDto dto : pageImagerySyncDto.getContent()) {
boolean isTfwFile = true;
isTfwFile = FIleChecker.checkTfw(dto.getMiddlePath()+dto.getFilename());
isTfwFile = FIleChecker.checkTfw(dto.getMiddlePath() + dto.getFilename());
boolean isGdalInfoTiffFile = true;
isGdalInfoTiffFile = FIleChecker.cmmndGdalInfo(dto.getCogMiddlePath()+dto.getCogFilename());
//isGdalInfoTiffFile = FIleChecker.cmmndGdalInfo("D:/kamco_cog/36713/36713073_cog.tif");
isGdalInfoTiffFile = FIleChecker.cmmndGdalInfo(dto.getCogMiddlePath() + dto.getCogFilename());
// isGdalInfoTiffFile = FIleChecker.cmmndGdalInfo("D:/kamco_cog/36713/36713073_cog.tif");
syncCnt = syncCnt + 1;
if( !isTfwFile )tfwErrCnt = tfwErrCnt + 1;
if( !isGdalInfoTiffFile )tifErrCnt = tifErrCnt + 1;
if (!isTfwFile) tfwErrCnt = tfwErrCnt + 1;
if (!isGdalInfoTiffFile) tifErrCnt = tifErrCnt + 1;
// 예: 특정 작업 수행
// someService.process(dto);
}
if( tfwErrCnt > 0 || tifErrCnt > 0 )flag = "ERROR";
if (tfwErrCnt > 0 || tifErrCnt > 0) flag = "ERROR";
return new ImageryDto.SyncReturn(flag, syncCnt, tfwErrCnt, tifErrCnt);
}
}

View File

@@ -41,12 +41,12 @@ public class MembersCoreService {
public Long saveMembers(MembersDto.AddReq addReq) {
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) {
throw new MemberException.DuplicateMemberException(
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
}
if (membersRepository.existsByEmail(addReq.getEmail())) {
throw new MemberException.DuplicateMemberException(
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
}
MemberEntity memberEntity = new MemberEntity();
@@ -66,7 +66,7 @@ public class MembersCoreService {
*/
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) {
memberEntity.setEmployeeNo(updateReq.getEmployeeNo());
@@ -93,13 +93,13 @@ public class MembersCoreService {
public void saveRoles(MembersDto.RolesDto rolesDto) {
MemberEntity memberEntity =
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
throw new MemberException.DuplicateMemberException(
MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
}
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
@@ -120,9 +120,9 @@ public class MembersCoreService {
*/
public void deleteRoles(MembersDto.RolesDto rolesDto) {
MemberEntity memberEntity =
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
membersRepository
.findByUUID(rolesDto.getUuid())
.orElseThrow(() -> new MemberNotFoundException());
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
@@ -142,9 +142,7 @@ public class MembersCoreService {
*/
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
MemberEntity memberEntity =
membersRepository
.findByUUID(uuid)
.orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
memberEntity.setStatus(statusDto.getStatus());
memberEntity.setUpdatedDttm(ZonedDateTime.now());
@@ -158,9 +156,7 @@ public class MembersCoreService {
*/
public void deleteAccount(UUID uuid) {
MemberEntity memberEntity =
membersRepository
.findByUUID(uuid)
.orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
memberArchivedEntityId.setUserId(memberEntity.getId());
@@ -193,10 +189,10 @@ public class MembersCoreService {
*/
public void resetPassword(Long id) {
MemberEntity memberEntity =
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
// 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(password, salt);

View File

@@ -1,14 +1,10 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import jakarta.validation.Valid;
import java.util.Optional;
import org.springframework.data.domain.Page;
public interface MapSheetMngFileCheckerRepositoryCustom {
Page<ImageryDto.SyncDto> findImagerySyncList(ImageryDto.@Valid searchReq searchReq);
}

View File

@@ -29,7 +29,6 @@ public class MapSheetMngFileCheckerRepositoryImpl extends QuerydslRepositorySupp
this.queryFactory = queryFactory;
}
@Override
public Page<ImageryDto.SyncDto> findImagerySyncList(ImageryDto.@Valid searchReq searchReq) {
@@ -41,53 +40,44 @@ public class MapSheetMngFileCheckerRepositoryImpl extends QuerydslRepositorySupp
}
List<ImageryDto.SyncDto> foundContent =
queryFactory
.select(
Projections.constructor(
ImageryDto.SyncDto.class,
imageryEntity.id,
imageryEntity.year,
imageryEntity.scene50k,
imageryEntity.scene5k,
imageryEntity.middlePath,
imageryEntity.cogMiddlePath,
imageryEntity.filename,
imageryEntity.cogFilename,
mapSheetMngHstEntity.hstUid
)
)
.from(imageryEntity)
.leftJoin(mapSheetMngHstEntity).on(
imageryEntity.year.eq(mapSheetMngHstEntity.mngYyyy)
.and(imageryEntity.scene5k.eq(mapSheetMngHstEntity.mapSheetNum.stringValue())))
.where(whereBuilder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
//.orderBy(mapSheetMngEntity.createdDttm.desc())
.fetch();
queryFactory
.select(
Projections.constructor(
ImageryDto.SyncDto.class,
imageryEntity.id,
imageryEntity.year,
imageryEntity.scene50k,
imageryEntity.scene5k,
imageryEntity.middlePath,
imageryEntity.cogMiddlePath,
imageryEntity.filename,
imageryEntity.cogFilename,
mapSheetMngHstEntity.hstUid))
.from(imageryEntity)
.leftJoin(mapSheetMngHstEntity)
.on(
imageryEntity
.year
.eq(mapSheetMngHstEntity.mngYyyy)
.and(imageryEntity.scene5k.eq(mapSheetMngHstEntity.mapSheetNum.stringValue())))
.where(whereBuilder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
// .orderBy(mapSheetMngEntity.createdDttm.desc())
.fetch();
Long countQuery =
queryFactory
.select(imageryEntity.id.count())
.from(imageryEntity)
.where(whereBuilder)
.fetchOne();
queryFactory
.select(imageryEntity.id.count())
.from(imageryEntity)
.where(whereBuilder)
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
private NumberExpression<Integer> rowNum() {
return Expressions.numberTemplate(
Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate);
}
}

View File

@@ -1,6 +1,5 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import jakarta.validation.Valid;
@@ -14,6 +13,4 @@ public interface MapSheetMngRepositoryCustom {
Page<MapSheetMngDto.MngDto> findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq);
Optional<MapSheetMngHstEntity> findMapSheetMngHstInfo(Long hstUid);
}

View File

@@ -1,12 +1,10 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
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.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.querydsl.core.BooleanBuilder;
@@ -141,7 +139,6 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Optional<MapSheetMngHstEntity> findMapSheetMngHstInfo(Long hstUid) {
return Optional.ofNullable(
@@ -169,7 +166,4 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
"{0} like '%" + searchReq.getSearchValue() + "%'",
mapSheetMngHstEntity.mapSheetNum));
}
}