2 Commits

Author SHA1 Message Date
37f8d728fa Merge pull request 'init spotless 적용' (#1) from feat/training_260202 into develop
Reviewed-on: #1
2026-02-02 15:49:14 +09:00
a1ffad1c4e init spotless 적용 2026-02-02 15:48:23 +09:00
153 changed files with 12870 additions and 12931 deletions

View File

@@ -64,7 +64,7 @@ public class FIleChecker {
} }
public static boolean verifyFileIntegrity(Path path, String expectedHash) public static boolean verifyFileIntegrity(Path path, String expectedHash)
throws IOException, NoSuchAlgorithmException { throws IOException, NoSuchAlgorithmException {
// 1. 알고리즘 선택 (SHA-256 권장, MD5는 보안상 비추천) // 1. 알고리즘 선택 (SHA-256 권장, MD5는 보안상 비추천)
MessageDigest digest = MessageDigest.getInstance("SHA-256"); MessageDigest digest = MessageDigest.getInstance("SHA-256");
@@ -278,60 +278,60 @@ public class FIleChecker {
try (Stream<Path> stream = Files.walk(startPath, maxDepth)) { try (Stream<Path> stream = Files.walk(startPath, maxDepth)) {
folderList = folderList =
stream stream
.filter(Files::isDirectory) .filter(Files::isDirectory)
.filter(p -> !p.toString().equals(dirPath)) .filter(p -> !p.toString().equals(dirPath))
.map( .map(
path -> { path -> {
int depth = path.getNameCount(); int depth = path.getNameCount();
String folderNm = path.getFileName().toString(); String folderNm = path.getFileName().toString();
String parentFolderNm = path.getParent().getFileName().toString(); String parentFolderNm = path.getParent().getFileName().toString();
String parentPath = path.getParent().toString(); String parentPath = path.getParent().toString();
String fullPath = path.toAbsolutePath().toString(); String fullPath = path.toAbsolutePath().toString();
boolean isValid = boolean isValid =
!NameValidator.containsKorean(folderNm) !NameValidator.containsKorean(folderNm)
&& !NameValidator.containsWhitespaceRegex(folderNm); && !NameValidator.containsWhitespaceRegex(folderNm);
File file = new File(fullPath); File file = new File(fullPath);
int childCnt = getChildFolderCount(file); int childCnt = getChildFolderCount(file);
String lastModified = getLastModified(file); String lastModified = getLastModified(file);
return new Folder( return new Folder(
folderNm, folderNm,
parentFolderNm, parentFolderNm,
parentPath, parentPath,
fullPath, fullPath,
depth, depth,
childCnt, childCnt,
lastModified, lastModified,
isValid); isValid);
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
if (sortType.equals("name") || sortType.equals("name asc")) { if (sortType.equals("name") || sortType.equals("name asc")) {
folderList.sort( folderList.sort(
Comparator.comparing( Comparator.comparing(
Folder::getFolderNm, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이 Folder::getFolderNm, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
)); ));
} else if (sortType.equals("name desc")) { } else if (sortType.equals("name desc")) {
folderList.sort( folderList.sort(
Comparator.comparing( Comparator.comparing(
Folder::getFolderNm, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이 Folder::getFolderNm, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
) )
.reversed()); .reversed());
} else if (sortType.equals("dttm desc")) { } else if (sortType.equals("dttm desc")) {
folderList.sort( folderList.sort(
Comparator.comparing( Comparator.comparing(
Folder::getLastModified, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이 Folder::getLastModified, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
) )
.reversed()); .reversed());
} else { } else {
folderList.sort( folderList.sort(
Comparator.comparing( Comparator.comparing(
Folder::getLastModified, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이 Folder::getLastModified, CASE_INSENSITIVE_ORDER // 대소문자 구분 없이
)); ));
} }
} catch (IOException e) { } catch (IOException e) {
@@ -382,13 +382,13 @@ public class FIleChecker {
} }
public static List<Basic> getFilesFromAllDepth( public static List<Basic> getFilesFromAllDepth(
String dir, String dir,
String targetFileNm, String targetFileNm,
String extension, String extension,
int maxDepth, int maxDepth,
String sortType, String sortType,
int startPos, int startPos,
int endPos) { int endPos) {
Path startPath = Paths.get(dir); Path startPath = Paths.get(dir);
String dirPath = dir; String dirPath = dir;
@@ -401,48 +401,48 @@ public class FIleChecker {
SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Predicate<Path> isTargetName = Predicate<Path> isTargetName =
p -> { p -> {
if (targetFileNm == null if (targetFileNm == null
|| targetFileNm.trim().isEmpty() || targetFileNm.trim().isEmpty()
|| targetFileNm.trim().equals("*")) { || targetFileNm.trim().equals("*")) {
return true; // 전체 파일 허용 return true; // 전체 파일 허용
} }
return p.getFileName().toString().contains(targetFileNm); return p.getFileName().toString().contains(targetFileNm);
}; };
try (Stream<Path> stream = Files.walk(startPath, maxDepth)) { try (Stream<Path> stream = Files.walk(startPath, maxDepth)) {
fileList = fileList =
stream stream
.filter(Files::isRegularFile) .filter(Files::isRegularFile)
.filter( .filter(
p -> p ->
extension == null extension == null
|| extension.equals("") || extension.equals("")
|| extension.equals("*") || extension.equals("*")
|| targetExtensions.contains(extractExtension(p))) || targetExtensions.contains(extractExtension(p)))
.sorted(getFileComparator(sortType)) .sorted(getFileComparator(sortType))
.filter(isTargetName) .filter(isTargetName)
.skip(startPos) .skip(startPos)
.limit(limit) .limit(limit)
.map( .map(
path -> { path -> {
// int depth = path.getNameCount(); // int depth = path.getNameCount();
String fileNm = path.getFileName().toString(); String fileNm = path.getFileName().toString();
String ext = FilenameUtils.getExtension(fileNm); String ext = FilenameUtils.getExtension(fileNm);
String parentFolderNm = path.getParent().getFileName().toString(); String parentFolderNm = path.getParent().getFileName().toString();
String parentPath = path.getParent().toString(); String parentPath = path.getParent().toString();
String fullPath = path.toAbsolutePath().toString(); String fullPath = path.toAbsolutePath().toString();
File file = new File(fullPath); File file = new File(fullPath);
long fileSize = file.length(); long fileSize = file.length();
String lastModified = dttmFormat.format(new Date(file.lastModified())); String lastModified = dttmFormat.format(new Date(file.lastModified()));
return new Basic( return new Basic(
fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified); fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified);
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
} catch (IOException e) { } catch (IOException e) {
System.err.println("파일 I/O 오류 발생: " + e.getMessage()); System.err.println("파일 I/O 오류 발생: " + e.getMessage());
@@ -452,7 +452,7 @@ public class FIleChecker {
} }
public static List<Basic> getFilesFromAllDepth( public static List<Basic> getFilesFromAllDepth(
String dir, String targetFileNm, String extension) { String dir, String targetFileNm, String extension) {
return FIleChecker.getFilesFromAllDepth(dir, targetFileNm, extension, 100, "name", 0, 100); return FIleChecker.getFilesFromAllDepth(dir, targetFileNm, extension, 100, "name", 0, 100);
} }
@@ -460,10 +460,10 @@ public class FIleChecker {
public static int getFileCountFromAllDepth(String dir, String targetFileNm, String extension) { public static int getFileCountFromAllDepth(String dir, String targetFileNm, String extension) {
List<FIleChecker.Basic> basicList = List<FIleChecker.Basic> basicList =
FIleChecker.getFilesFromAllDepth(dir, targetFileNm, extension); FIleChecker.getFilesFromAllDepth(dir, targetFileNm, extension);
return (int) return (int)
basicList.stream().filter(dto -> dto.getExtension().toString().equals(extension)).count(); basicList.stream().filter(dto -> dto.getExtension().toString().equals(extension)).count();
} }
public static Long getFileTotSize(List<FIleChecker.Basic> files) { public static Long getFileTotSize(List<FIleChecker.Basic> files) {
@@ -490,8 +490,8 @@ public class FIleChecker {
return true; return true;
} }
public static boolean multipartChunkSaveTo(
public static boolean multipartChunkSaveTo(MultipartFile mfile, String targetPath, int chunkIndex) { MultipartFile mfile, String targetPath, int chunkIndex) {
File dest = new File(targetPath, String.valueOf(chunkIndex)); File dest = new File(targetPath, String.valueOf(chunkIndex));
boolean fileUpload = true; boolean fileUpload = true;
@@ -508,8 +508,6 @@ public class FIleChecker {
return FileSystemUtils.deleteRecursively(new File(path)); return FileSystemUtils.deleteRecursively(new File(path));
} }
public static boolean validationMultipart(MultipartFile mfile) { public static boolean validationMultipart(MultipartFile mfile) {
// 파일 유효성 검증 // 파일 유효성 검증
if (mfile == null || mfile.isEmpty() || mfile.getSize() == 0) { if (mfile == null || mfile.isEmpty() || mfile.getSize() == 0) {
@@ -536,10 +534,10 @@ public class FIleChecker {
// "java, class" -> ["java", " class"] -> [".java", ".class"] // "java, class" -> ["java", " class"] -> [".java", ".class"]
return Arrays.stream(extensionString.split(",")) return Arrays.stream(extensionString.split(","))
.map(ext -> ext.trim()) .map(ext -> ext.trim())
.filter(ext -> !ext.isEmpty()) .filter(ext -> !ext.isEmpty())
.map(ext -> "." + ext.toLowerCase()) .map(ext -> "." + ext.toLowerCase())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
public static String extractExtension(Path path) { public static String extractExtension(Path path) {
@@ -559,17 +557,17 @@ public class FIleChecker {
// 파일 이름 비교 기본 Comparator (대소문자 무시) // 파일 이름 비교 기본 Comparator (대소문자 무시)
Comparator<Path> nameComparator = Comparator<Path> nameComparator =
Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER);
Comparator<Path> dateComparator = Comparator<Path> dateComparator =
Comparator.comparing( Comparator.comparing(
path -> { path -> {
try { try {
return Files.getLastModifiedTime(path); return Files.getLastModifiedTime(path);
} catch (IOException e) { } catch (IOException e) {
return FileTime.fromMillis(0); return FileTime.fromMillis(0);
} }
}); });
if ("name desc".equalsIgnoreCase(sortType)) { if ("name desc".equalsIgnoreCase(sortType)) {
return nameComparator.reversed(); return nameComparator.reversed();
@@ -634,14 +632,14 @@ public class FIleChecker {
private final Boolean isValid; private final Boolean isValid;
public Folder( public Folder(
String folderNm, String folderNm,
String parentFolderNm, String parentFolderNm,
String parentPath, String parentPath,
String fullPath, String fullPath,
int depth, int depth,
long childCnt, long childCnt,
String lastModified, String lastModified,
Boolean isValid) { Boolean isValid) {
this.folderNm = folderNm; this.folderNm = folderNm;
this.parentFolderNm = parentFolderNm; this.parentFolderNm = parentFolderNm;
this.parentPath = parentPath; this.parentPath = parentPath;
@@ -666,13 +664,13 @@ public class FIleChecker {
private final String lastModified; private final String lastModified;
public Basic( public Basic(
String fileNm, String fileNm,
String parentFolderNm, String parentFolderNm,
String parentPath, String parentPath,
String fullPath, String fullPath,
String extension, String extension,
long fileSize, long fileSize,
String lastModified) { String lastModified) {
this.fileNm = fileNm; this.fileNm = fileNm;
this.parentFolderNm = parentFolderNm; this.parentFolderNm = parentFolderNm;
this.parentPath = parentPath; this.parentPath = parentPath;

View File

@@ -56,7 +56,7 @@ public class AuthController {
@ApiResponses({ @ApiResponses({
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "로그인 성공", description = "로그인 성공1",
content = @Content(schema = @Schema(implementation = TokenResponse.class))), content = @Content(schema = @Schema(implementation = TokenResponse.class))),
@ApiResponse( @ApiResponse(
responseCode = "401", responseCode = "401",
@@ -96,10 +96,10 @@ public class AuthController {
} }
"""), """),
@ExampleObject( @ExampleObject(
name = "사용 중지 된 계정의 로그인 시도", name = "사용 중지 된 계정의 로그인 시도",
description = "사용 중지 된 계정의 로그인 시도", description = "사용 중지 된 계정의 로그인 시도",
value = value =
""" """
{ {
"code": "INACTIVE_ID", "code": "INACTIVE_ID",
"message": "사용할 수 없는 계정입니다." "message": "사용할 수 없는 계정입니다."
@@ -118,7 +118,7 @@ public class AuthController {
// 사용자 상태 조회 // 사용자 상태 조회
String status = authService.getUserStatus(request); String status = authService.getUserStatus(request);
if(StatusType.INACTIVE.getId().equals(status)) { if (StatusType.INACTIVE.getId().equals(status)) {
throw new CustomApiException("INACTIVE_ID", HttpStatus.UNAUTHORIZED); throw new CustomApiException("INACTIVE_ID", HttpStatus.UNAUTHORIZED);
} }

View File

@@ -144,7 +144,8 @@ public class MembersCoreService {
MemberEntity memberEntity = MemberEntity memberEntity =
membersRepository membersRepository
.findByEmployeeNo(request.getUsername()) .findByEmployeeNo(request.getUsername())
.orElseThrow(() -> new CustomApiException("LOGIN_ID_NOT_FOUND", HttpStatus.UNAUTHORIZED)); .orElseThrow(
() -> new CustomApiException("LOGIN_ID_NOT_FOUND", HttpStatus.UNAUTHORIZED));
return memberEntity.getStatus(); return memberEntity.getStatus();
} }

View File

@@ -1,9 +1,7 @@
package com.kamco.cd.training.postgres.core; package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import com.kamco.cd.training.postgres.repository.upload.UploadSessionRepository; import com.kamco.cd.training.postgres.repository.upload.UploadSessionRepository;
import com.kamco.cd.training.upload.dto.UploadDto; import com.kamco.cd.training.upload.dto.UploadDto;
import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -13,8 +11,7 @@ public class UploadSessionCoreService {
private final UploadSessionRepository uploadSessionRepository; private final UploadSessionRepository uploadSessionRepository;
public void createUploadSession(UploadDto.UploadAddReq addReq) public void createUploadSession(UploadDto.UploadAddReq addReq) {
{
/* /*
UUID newUuid = UUID.randomUUID(); UUID newUuid = UUID.randomUUID();
@@ -40,18 +37,17 @@ public class UploadSessionCoreService {
*/ */
uploadSessionRepository.insertUploadSession(addReq); uploadSessionRepository.insertUploadSession(addReq);
} }
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi){ public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) {
return uploadSessionRepository.findByDatasetUid(datasetId, uploadDivi); return uploadSessionRepository.findByDatasetUid(datasetId, uploadDivi);
} }
public UploadDto.uploadDto findByUuid(String uuid){ public UploadDto.uploadDto findByUuid(String uuid) {
return uploadSessionRepository.findByUuid(uuid); return uploadSessionRepository.findByUuid(uuid);
} }
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq){ public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq) {
uploadSessionRepository.updateUploadSessionStatus(addReq); uploadSessionRepository.updateUploadSessionStatus(addReq);
} }
} }

View File

@@ -1,6 +1,5 @@
package com.kamco.cd.training.postgres.entity; package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.upload.dto.UploadDto;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
@@ -95,8 +94,4 @@ public class UploadSessionEntity {
this.chunkIndex = 0; this.chunkIndex = 0;
} }
} }
} }

View File

@@ -1,22 +1,14 @@
package com.kamco.cd.training.postgres.repository.upload; package com.kamco.cd.training.postgres.repository.upload;
import com.kamco.cd.training.upload.dto.UploadDto; import com.kamco.cd.training.upload.dto.UploadDto;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page;
public interface UploadSessionRepositoryCustom { public interface UploadSessionRepositoryCustom {
void insertUploadSession(UploadDto.UploadAddReq addReq); void insertUploadSession(UploadDto.UploadAddReq addReq);
UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi); UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi);
UploadDto.uploadDto findByUuid(String uuid); UploadDto.uploadDto findByUuid(String uuid);
void updateUploadSessionStatus(UploadDto.UploadAddReq addReq); void updateUploadSessionStatus(UploadDto.UploadAddReq addReq);
} }

View File

@@ -1,31 +1,16 @@
package com.kamco.cd.training.postgres.repository.upload; package com.kamco.cd.training.postgres.repository.upload;
import static com.kamco.cd.training.postgres.entity.QUploadSessionEntity.uploadSessionEntity; import static com.kamco.cd.training.postgres.entity.QUploadSessionEntity.uploadSessionEntity;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity; import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import com.kamco.cd.training.upload.dto.UploadDto; import com.kamco.cd.training.upload.dto.UploadDto;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext; import jakarta.persistence.PersistenceContext;
import jakarta.validation.Valid;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.hibernate.query.Query;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class UploadSessionRepositoryImpl extends QuerydslRepositorySupport public class UploadSessionRepositoryImpl extends QuerydslRepositorySupport
@@ -44,113 +29,104 @@ public class UploadSessionRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public void insertUploadSession(UploadDto.UploadAddReq addReq) { public void insertUploadSession(UploadDto.UploadAddReq addReq) {
long execCnt = long execCnt =
queryFactory queryFactory
.insert(uploadSessionEntity) .insert(uploadSessionEntity)
.columns( .columns(
uploadSessionEntity.uploadId, uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId, uploadSessionEntity.datasetId,
uploadSessionEntity.fileName, uploadSessionEntity.fileName,
uploadSessionEntity.fileSize, uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath, uploadSessionEntity.finalPath,
uploadSessionEntity.status, uploadSessionEntity.status,
uploadSessionEntity.tempPath, uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex, uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex, uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.uploadDivi, uploadSessionEntity.uploadDivi,
uploadSessionEntity.fileHash, uploadSessionEntity.fileHash,
uploadSessionEntity.uuid uploadSessionEntity.uuid)
) .values(
.values( addReq.getUploadId(),
addReq.getUploadId(), addReq.getDatasetId(),
addReq.getDatasetId(), addReq.getFileName(),
addReq.getFileName(), addReq.getFileSize(),
addReq.getFileSize(), addReq.getFinalPath(),
addReq.getFinalPath(), addReq.getStatus(),
addReq.getStatus(), addReq.getTempPath(),
addReq.getTempPath(), addReq.getChunkIndex(),
addReq.getChunkIndex(), addReq.getChunkTotalIndex(),
addReq.getChunkTotalIndex(), addReq.getUploadDivi(),
addReq.getUploadDivi(), addReq.getFileHash(),
addReq.getFileHash(), addReq.getUuid())
addReq.getUuid() .execute();
)
.execute();
} }
@Override @Override
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) { public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) {
UploadDto.uploadDto foundContent = UploadDto.uploadDto foundContent =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
UploadDto.uploadDto.class, UploadDto.uploadDto.class,
uploadSessionEntity.uploadId, uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId, uploadSessionEntity.datasetId,
uploadSessionEntity.fileName, uploadSessionEntity.fileName,
uploadSessionEntity.fileSize, uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath, uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi, uploadSessionEntity.uploadDivi,
uploadSessionEntity.status, uploadSessionEntity.status,
uploadSessionEntity.tempPath, uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex, uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex, uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash, uploadSessionEntity.fileHash,
uploadSessionEntity.uuid uploadSessionEntity.uuid))
)) .from(uploadSessionEntity)
.from(uploadSessionEntity) .where(
.where(uploadSessionEntity.datasetId.eq(datasetId) uploadSessionEntity
.and(uploadSessionEntity.uploadDivi.eq(uploadDivi))) .datasetId
.limit(1) .eq(datasetId)
.fetchOne(); .and(uploadSessionEntity.uploadDivi.eq(uploadDivi)))
.limit(1)
.fetchOne();
return foundContent; return foundContent;
} }
@Override @Override
public UploadDto.uploadDto findByUuid(String uuid) { public UploadDto.uploadDto findByUuid(String uuid) {
UploadDto.uploadDto foundContent = UploadDto.uploadDto foundContent =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
UploadDto.uploadDto.class, UploadDto.uploadDto.class,
uploadSessionEntity.uploadId, uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId, uploadSessionEntity.datasetId,
uploadSessionEntity.fileName, uploadSessionEntity.fileName,
uploadSessionEntity.fileSize, uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath, uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi, uploadSessionEntity.uploadDivi,
uploadSessionEntity.status, uploadSessionEntity.status,
uploadSessionEntity.tempPath, uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex, uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex, uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash, uploadSessionEntity.fileHash,
uploadSessionEntity.uuid uploadSessionEntity.uuid))
)) .from(uploadSessionEntity)
.from(uploadSessionEntity) .where(uploadSessionEntity.uuid.eq(UUID.fromString(uuid)))
.where(uploadSessionEntity.uuid.eq(UUID.fromString(uuid))) .limit(1)
.limit(1) .fetchOne();
.fetchOne();
return foundContent; return foundContent;
} }
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq) {
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq){
long fileCount = long fileCount =
queryFactory queryFactory
.update(uploadSessionEntity) .update(uploadSessionEntity)
.set(uploadSessionEntity.chunkIndex, addReq.getChunkIndex()) .set(uploadSessionEntity.chunkIndex, addReq.getChunkIndex())
.set(uploadSessionEntity.status, addReq.getStatus()) .set(uploadSessionEntity.status, addReq.getStatus())
.where(uploadSessionEntity.uploadId.eq(addReq.getUploadId())) .where(uploadSessionEntity.uploadId.eq(addReq.getUploadId()))
.execute(); .execute();
} }
} }

View File

@@ -75,7 +75,6 @@ public class UploadApiController {
return ApiResponseDto.ok(uploadService.uploadChunk(upAddReqDto, chunkFile)); return ApiResponseDto.ok(uploadService.uploadChunk(upAddReqDto, chunkFile));
} }
@Operation(summary = "업로드 완료된 파일 병합", description = "업로드 완료 및 파일 병합을 요청합니다.") @Operation(summary = "업로드 완료된 파일 병합", description = "업로드 완료 및 파일 병합을 요청합니다.")
@ApiResponses( @ApiResponses(
value = { value = {
@@ -85,8 +84,7 @@ public class UploadApiController {
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@PutMapping("/chunk-upload-complete/{uuid}") @PutMapping("/chunk-upload-complete/{uuid}")
public ApiResponseDto<DmlReturn> completeUpload( public ApiResponseDto<DmlReturn> completeUpload(@PathVariable String uuid) {
@PathVariable String uuid) {
return ApiResponseDto.ok(uploadService.completeUpload(uuid)); return ApiResponseDto.ok(uploadService.completeUpload(uuid));
} }

View File

@@ -154,7 +154,6 @@ public class UploadDto {
@Schema(description = "파일명", example = "data.zip") @Schema(description = "파일명", example = "data.zip")
private String fileName; private String fileName;
@Schema(description = "파일 크기 (bytes)", example = "10737418240") @Schema(description = "파일 크기 (bytes)", example = "10737418240")
private Long fileSize; private Long fileSize;
@@ -176,7 +175,6 @@ public class UploadDto {
@Schema(description = "총 청크 Index", example = "100") @Schema(description = "총 청크 Index", example = "100")
private Integer chunkTotalIndex; private Integer chunkTotalIndex;
@Schema( @Schema(
description = "파일해쉬", description = "파일해쉬",
example = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") example = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
@@ -184,7 +182,6 @@ public class UploadDto {
@Schema(description = "uuid") @Schema(description = "uuid")
private UUID uuid; private UUID uuid;
} }
@Schema(name = "UploadRes", description = "업로드 수행 후 리턴") @Schema(name = "UploadRes", description = "업로드 수행 후 리턴")
@@ -203,9 +200,8 @@ public class UploadDto {
if (this.chunkTotalIndex == 0) { if (this.chunkTotalIndex == 0) {
return 0.0; return 0.0;
} }
return (double) (this.chunkIndex+1) / (this.chunkTotalIndex+1) * 100.0; return (double) (this.chunkIndex + 1) / (this.chunkTotalIndex + 1) * 100.0;
} }
} }
@Schema(name = "DmlReturn", description = "수행 후 리턴") @Schema(name = "DmlReturn", description = "수행 후 리턴")

View File

@@ -4,9 +4,6 @@ import com.kamco.cd.training.common.utils.FIleChecker;
import com.kamco.cd.training.postgres.core.UploadSessionCoreService; import com.kamco.cd.training.postgres.core.UploadSessionCoreService;
import com.kamco.cd.training.upload.dto.UploadDto; import com.kamco.cd.training.upload.dto.UploadDto;
import com.kamco.cd.training.upload.dto.UploadDto.DmlReturn; import com.kamco.cd.training.upload.dto.UploadDto.DmlReturn;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.Files; import java.nio.file.Files;
@@ -55,21 +52,20 @@ public class UploadService {
UploadDto.UploadRes upRes = new UploadDto.UploadRes(); UploadDto.UploadRes upRes = new UploadDto.UploadRes();
long datasetId = upAddReqDto.getDatasetId(); long datasetId = upAddReqDto.getDatasetId();
String uploadId = System.currentTimeMillis()+""; String uploadId = System.currentTimeMillis() + "";
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
String tmpDataSetDir = ""; String tmpDataSetDir = "";
String fianlDir = ""; String fianlDir = "";
String uploadDivi = upAddReqDto.getUploadDivi(); String uploadDivi = upAddReqDto.getUploadDivi();
//String fileName = file.getOriginalFilename(); // String fileName = file.getOriginalFilename();
String fileName = upAddReqDto.getFileName(); String fileName = upAddReqDto.getFileName();
Integer chunkIndex = upAddReqDto.getChunkIndex(); Integer chunkIndex = upAddReqDto.getChunkIndex();
Integer chunkTotalIndex = upAddReqDto.getChunkTotalIndex(); Integer chunkTotalIndex = upAddReqDto.getChunkTotalIndex();
String status = "UPLOADING"; String status = "UPLOADING";
if( uploadDivi.equals("dataset")) if (uploadDivi.equals("dataset")) {
{ tmpDataSetDir = datasetTmpDir + uuid + "/";
tmpDataSetDir = datasetTmpDir+uuid+"/"; fianlDir = datasetDir + uuid + "/";
fianlDir = datasetDir+uuid+"/";
} }
upAddReqDto.setUuid(uuid); upAddReqDto.setUuid(uuid);
@@ -79,32 +75,30 @@ public class UploadService {
upAddReqDto.setTempPath(tmpDataSetDir); upAddReqDto.setTempPath(tmpDataSetDir);
upAddReqDto.setFinalPath(fianlDir); upAddReqDto.setFinalPath(fianlDir);
//세션 신규,중복체크(초기화 포함) // 세션 신규,중복체크(초기화 포함)
UploadDto.uploadDto dto = this.checkUploadSession(upAddReqDto, upRes); UploadDto.uploadDto dto = this.checkUploadSession(upAddReqDto, upRes);
if( !upRes.getRes().equals("success") )return upRes; if (!upRes.getRes().equals("success")) return upRes;
if( dto != null ) if (dto != null) {
{ tmpDataSetDir = dto.getTempPath();
tmpDataSetDir = dto.getTempPath();
fianlDir = dto.getFinalPath(); fianlDir = dto.getFinalPath();
} }
//폴더 생성 및 체크 // 폴더 생성 및 체크
if( ! checkChunkFoler(upRes, tmpDataSetDir, fianlDir) )return upRes; if (!checkChunkFoler(upRes, tmpDataSetDir, fianlDir)) return upRes;
//chunk저장하기 // chunk저장하기
if( ! FIleChecker.multipartChunkSaveTo(file, tmpDataSetDir, chunkIndex ) ) if (!FIleChecker.multipartChunkSaveTo(file, tmpDataSetDir, chunkIndex)) {
{
upRes.setRes("fail"); upRes.setRes("fail");
upRes.setResMsg("chunkIndex:"+chunkIndex+" 업로드 애러"); upRes.setResMsg("chunkIndex:" + chunkIndex + " 업로드 애러");
} }
//chunk완료시 merge 및 폴더에 저장 // chunk완료시 merge 및 폴더에 저장
if( chunkIndex == chunkTotalIndex ) { if (chunkIndex == chunkTotalIndex) {
//upAddReqDto.setUploadId(dto.getUploadId()); // upAddReqDto.setUploadId(dto.getUploadId());
//upAddReqDto.setStatus("MERGING"); // upAddReqDto.setStatus("MERGING");
//uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); // uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto);
/* /*
try { try {
@@ -120,7 +114,6 @@ public class UploadService {
upAddReqDto.setUploadId(dto.getUploadId()); upAddReqDto.setUploadId(dto.getUploadId());
upAddReqDto.setStatus("COMPLETE"); upAddReqDto.setStatus("COMPLETE");
uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto);
} }
return upRes; return upRes;
@@ -132,26 +125,23 @@ public class UploadService {
UploadDto.uploadDto dto = uploadSessionCoreService.findByUuid(uuid); UploadDto.uploadDto dto = uploadSessionCoreService.findByUuid(uuid);
try { try {
this.mergeChunks(dto.getTempPath(), dto.getFinalPath(), dto.getFileName(), dto.getChunkTotalIndex()); this.mergeChunks(
dto.getTempPath(), dto.getFinalPath(), dto.getFileName(), dto.getChunkTotalIndex());
} catch (IOException e) { } catch (IOException e) {
return new DmlReturn("mergingfail", "chunk파일 merge 애러"); return new DmlReturn("mergingfail", "chunk파일 merge 애러");
} }
return new DmlReturn("success", "병합(merge) 정상처리되었습니다."); return new DmlReturn("success", "병합(merge) 정상처리되었습니다.");
} }
public boolean checkChunkFoler(UploadDto.UploadRes upRes, String tmpDataSetDir, String fianlDir) public boolean checkChunkFoler(UploadDto.UploadRes upRes, String tmpDataSetDir, String fianlDir) {
{ if (!FIleChecker.mkDir(tmpDataSetDir)) {
if( ! FIleChecker.mkDir(tmpDataSetDir) )
{
upRes.setRes("fail"); upRes.setRes("fail");
upRes.setRes("CHUNK 폴더 생성 ERROR"); upRes.setRes("CHUNK 폴더 생성 ERROR");
return false; return false;
} }
if( ! FIleChecker.mkDir(fianlDir) ) if (!FIleChecker.mkDir(fianlDir)) {
{
upRes.setRes("fail"); upRes.setRes("fail");
upRes.setRes("업로드 완료 폴더 생성 ERROR"); upRes.setRes("업로드 완료 폴더 생성 ERROR");
return false; return false;
@@ -160,28 +150,28 @@ public class UploadService {
return true; return true;
} }
public UploadDto.uploadDto checkUploadSession(
public UploadDto.uploadDto checkUploadSession(UploadDto.UploadAddReq upAddReqDto, UploadDto.UploadRes upRes) { UploadDto.UploadAddReq upAddReqDto, UploadDto.UploadRes upRes) {
upRes.setRes("success"); upRes.setRes("success");
upRes.setResMsg("정상처리되었습니다."); upRes.setResMsg("정상처리되었습니다.");
UploadDto.uploadDto dto = uploadSessionCoreService.findByDatasetUid(upAddReqDto.getDatasetId(), upAddReqDto.getUploadDivi()); UploadDto.uploadDto dto =
uploadSessionCoreService.findByDatasetUid(
upAddReqDto.getDatasetId(), upAddReqDto.getUploadDivi());
if( upAddReqDto.getChunkIndex() == 0 ) { if (upAddReqDto.getChunkIndex() == 0) {
if( dto != null ) if (dto != null) {
{
upRes.setRes("duplicate"); upRes.setRes("duplicate");
upRes.setResMsg("이미 진행중인 업로드세션입니다."); upRes.setResMsg("이미 진행중인 업로드세션입니다.");
return dto; return dto;
} }
upAddReqDto.setStatus("UPLOADING"); upAddReqDto.setStatus("UPLOADING");
upRes.setUuid( upAddReqDto.getUuid().toString() ); upRes.setUuid(upAddReqDto.getUuid().toString());
uploadSessionCoreService.createUploadSession(upAddReqDto); uploadSessionCoreService.createUploadSession(upAddReqDto);
} } else {
else { if (dto == null) {
if( dto == null ){
upRes.setRes("nosession"); upRes.setRes("nosession");
upRes.setResMsg("업로드 세션이 존재하지 않습니다."); upRes.setResMsg("업로드 세션이 존재하지 않습니다.");
return dto; return dto;
@@ -192,22 +182,22 @@ public class UploadService {
uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto);
} }
if( dto != null )upRes.setUuid( dto.getUuid().toString() ); if (dto != null) upRes.setUuid(dto.getUuid().toString());
upRes.setChunkIndex(upAddReqDto.getChunkIndex()); upRes.setChunkIndex(upAddReqDto.getChunkIndex());
upRes.setChunkTotalIndex(upAddReqDto.getChunkTotalIndex()); upRes.setChunkTotalIndex(upAddReqDto.getChunkTotalIndex());
return dto; return dto;
} }
public void mergeChunks(String tmpDir, String fianlDir, String fileName, int chunkTotalIndex) throws IOException { public void mergeChunks(String tmpDir, String fianlDir, String fileName, int chunkTotalIndex)
throws IOException {
Path outputPath = Paths.get(fianlDir, fileName); Path outputPath = Paths.get(fianlDir, fileName);
try (FileChannel outChannel = FileChannel.open(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { try (FileChannel outChannel =
FileChannel.open(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
for (int i = 0; i <= chunkTotalIndex; i++) { for (int i = 0; i <= chunkTotalIndex; i++) {
Path chunkPath = Paths.get(tmpDir, i+""); Path chunkPath = Paths.get(tmpDir, i + "");
try (FileChannel inChannel = FileChannel.open(chunkPath, StandardOpenOption.READ)) { try (FileChannel inChannel = FileChannel.open(chunkPath, StandardOpenOption.READ)) {
long transferred = 0; long transferred = 0;
@@ -221,10 +211,7 @@ public class UploadService {
} }
} }
//병합후 임시 폴더 삭제 // 병합후 임시 폴더 삭제
FIleChecker.deleteFolder(tmpDir); FIleChecker.deleteFolder(tmpDir);
} }
} }