업로드 로직 86으로 수행하기 수정 #34
@@ -2,6 +2,7 @@ package com.kamco.cd.training.common.utils;
|
|||||||
|
|
||||||
import static java.lang.String.CASE_INSENSITIVE_ORDER;
|
import static java.lang.String.CASE_INSENSITIVE_ORDER;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.ChannelExec;
|
||||||
import com.jcraft.jsch.ChannelSftp;
|
import com.jcraft.jsch.ChannelSftp;
|
||||||
import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
@@ -800,4 +801,97 @@ public class FIleChecker {
|
|||||||
if (session != null) session.disconnect();
|
if (session != null) session.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void unzipOn86Server(String zipPath, String targetDir) {
|
||||||
|
|
||||||
|
String host = "192.168.2.86";
|
||||||
|
String user = "kcomu";
|
||||||
|
String password = "Kamco2025!";
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
ChannelExec channel = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSch jsch = new JSch();
|
||||||
|
|
||||||
|
session = jsch.getSession(user, host, 22);
|
||||||
|
session.setPassword(password);
|
||||||
|
|
||||||
|
Properties config = new Properties();
|
||||||
|
config.put("StrictHostKeyChecking", "no");
|
||||||
|
session.setConfig(config);
|
||||||
|
|
||||||
|
session.connect(10_000);
|
||||||
|
|
||||||
|
String command = "unzip -o " + zipPath + " -d " + targetDir;
|
||||||
|
|
||||||
|
channel = (ChannelExec) session.openChannel("exec");
|
||||||
|
channel.setCommand(command);
|
||||||
|
channel.setErrStream(System.err);
|
||||||
|
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
channel.connect();
|
||||||
|
|
||||||
|
// 출력 읽기(선택)
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
|
||||||
|
while (br.readLine() != null) {
|
||||||
|
// 필요하면 로그
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (channel != null) channel.disconnect();
|
||||||
|
if (session != null) session.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> execCommandAndReadLines(String command) {
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
|
||||||
|
String host = "192.168.2.86";
|
||||||
|
String user = "kcomu";
|
||||||
|
String password = "Kamco2025!";
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
ChannelExec channel = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSch jsch = new JSch();
|
||||||
|
|
||||||
|
session = jsch.getSession(user, host, 22);
|
||||||
|
session.setPassword(password);
|
||||||
|
|
||||||
|
Properties config = new Properties();
|
||||||
|
config.put("StrictHostKeyChecking", "no");
|
||||||
|
session.setConfig(config);
|
||||||
|
|
||||||
|
session.connect(10_000);
|
||||||
|
|
||||||
|
channel = (ChannelExec) session.openChannel("exec");
|
||||||
|
channel.setCommand(command);
|
||||||
|
channel.setInputStream(null);
|
||||||
|
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
channel.connect();
|
||||||
|
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
result.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("remote command failed : " + command, e);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (channel != null) channel.disconnect();
|
||||||
|
if (session != null) session.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ public class DatasetApiController {
|
|||||||
public ApiResponseDto<ApiResponseDto.ResponseObj> insertDataset(
|
public ApiResponseDto<ApiResponseDto.ResponseObj> insertDataset(
|
||||||
@RequestBody @Valid DatasetDto.AddReq addReq) {
|
@RequestBody @Valid DatasetDto.AddReq addReq) {
|
||||||
|
|
||||||
return ApiResponseDto.ok(datasetService.insertDataset(addReq));
|
return ApiResponseDto.ok(
|
||||||
|
datasetService.insertDatasetTo86(addReq)); // TODO 서버 옮긴 이후에 다시 insertDataset 로 원복하기
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "객체별 파일 Path 조회", description = "파일 Path 조회")
|
@Operation(summary = "객체별 파일 Path 조회", description = "파일 Path 조회")
|
||||||
|
|||||||
@@ -158,6 +158,43 @@ public class DatasetService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public ResponseObj insertDatasetTo86(@Valid AddReq addReq) {
|
||||||
|
|
||||||
|
Long datasetUid = null; // master id 값, 등록하면서 가져올 예정
|
||||||
|
|
||||||
|
// 압축 해제
|
||||||
|
FIleChecker.unzipOn86Server(
|
||||||
|
addReq.getFilePath() + addReq.getFileName(),
|
||||||
|
addReq.getFilePath() + addReq.getFileName().replace(".zip", ""));
|
||||||
|
|
||||||
|
// 해제한 폴더 읽어서 데이터 저장
|
||||||
|
List<Map<String, Object>> list =
|
||||||
|
getUnzipDatasetFilesTo86(
|
||||||
|
addReq.getFilePath() + addReq.getFileName().replace(".zip", ""), "train");
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (Map<String, Object> map : list) {
|
||||||
|
datasetUid =
|
||||||
|
this.insertTrainTestData(map, addReq, idx, datasetUid, "train"); // train 데이터 insert
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> testList =
|
||||||
|
getUnzipDatasetFilesTo86(
|
||||||
|
addReq.getFilePath() + addReq.getFileName().replace(".zip", ""), "test");
|
||||||
|
|
||||||
|
int testIdx = 0;
|
||||||
|
for (Map<String, Object> test : testList) {
|
||||||
|
datasetUid =
|
||||||
|
this.insertTrainTestData(test, addReq, testIdx, datasetUid, "test"); // test 데이터 insert
|
||||||
|
testIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
datasetCoreService.updateDatasetUploadStatus(datasetUid);
|
||||||
|
return new ResponseObj(ApiResponseCode.OK, "업로드 성공하였습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseObj insertDataset(@Valid AddReq addReq) {
|
public ResponseObj insertDataset(@Valid AddReq addReq) {
|
||||||
|
|
||||||
@@ -356,4 +393,85 @@ public class DatasetService {
|
|||||||
public String getFilePathByUUIDPathType(UUID uuid, String pathType) {
|
public String getFilePathByUUIDPathType(UUID uuid, String pathType) {
|
||||||
return datasetCoreService.getFilePathByUUIDPathType(uuid, pathType);
|
return datasetCoreService.getFilePathByUUIDPathType(uuid, pathType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Map<String, Object>> getUnzipDatasetFilesTo86(String unzipRootPath, String subDir) {
|
||||||
|
|
||||||
|
// String root = Paths.get(unzipRootPath)
|
||||||
|
// .resolve(subDir)
|
||||||
|
// .toString();
|
||||||
|
//
|
||||||
|
String root = normalizeLinuxPath(unzipRootPath + "/" + subDir);
|
||||||
|
|
||||||
|
Map<String, Map<String, Object>> grouped = new HashMap<>();
|
||||||
|
|
||||||
|
for (String dirName : LABEL_DIRS) {
|
||||||
|
|
||||||
|
String remoteDir = root + "/" + dirName;
|
||||||
|
|
||||||
|
// 1. 86 서버에서 해당 디렉토리의 파일 목록 조회
|
||||||
|
List<String> files = listFilesOn86Server(remoteDir);
|
||||||
|
|
||||||
|
if (files.isEmpty()) {
|
||||||
|
throw new IllegalStateException("폴더가 존재하지 않거나 파일이 없습니다 : " + remoteDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String fullPath : files) {
|
||||||
|
|
||||||
|
String fileName = Paths.get(fullPath).getFileName().toString();
|
||||||
|
String baseName = getBaseName(fileName);
|
||||||
|
|
||||||
|
Map<String, Object> data = grouped.computeIfAbsent(baseName, k -> new HashMap<>());
|
||||||
|
|
||||||
|
data.put("baseName", baseName);
|
||||||
|
|
||||||
|
if ("label-json".equals(dirName)) {
|
||||||
|
|
||||||
|
// 2. json 내용도 86 서버에서 읽어서 가져와야 함
|
||||||
|
String json = readRemoteFileAsString(fullPath);
|
||||||
|
|
||||||
|
data.put("label-json", parseJson(json));
|
||||||
|
data.put("geojson_path", fullPath);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data.put(dirName, fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>(grouped.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> listFilesOn86Server(String remoteDir) {
|
||||||
|
|
||||||
|
String command = "find " + escape(remoteDir) + " -maxdepth 1 -type f";
|
||||||
|
|
||||||
|
return FIleChecker.execCommandAndReadLines(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readRemoteFileAsString(String remoteFilePath) {
|
||||||
|
|
||||||
|
String command = "cat " + escape(remoteFilePath);
|
||||||
|
|
||||||
|
List<String> lines = FIleChecker.execCommandAndReadLines(command);
|
||||||
|
|
||||||
|
return String.join("\n", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode parseJson(String json) {
|
||||||
|
try {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
return mapper.readTree(json);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("JSON 파싱 실패", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String escape(String path) {
|
||||||
|
return "'" + path.replace("'", "'\"'\"'") + "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String normalizeLinuxPath(String path) {
|
||||||
|
return path.replace("\\", "/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user