[파일 업로드] tusHook 작업
- 멀티업로드 상태 업로드
This commit is contained in:
@@ -102,21 +102,9 @@ public class FileController {
|
||||
|
||||
@PostMapping("/tusHook")
|
||||
public ResponseEntity<ApiResponse<String>> tusHook(@RequestBody TusHookForm tusHookForm) {
|
||||
// log.info("tusHookForm: {}", tusHookForm);
|
||||
// fileService.insertFileAndSave(tusHookForm.tusHookDto());
|
||||
log.info("[tusHook] type={}", tusHookForm.getType());
|
||||
log.info("[tusHook] uploadId={}", tusHookForm.getTusHookEventForm().getTusHookUploadForm().getId());
|
||||
log.info("[tusHook] size={}", tusHookForm.getTusHookEventForm().getTusHookUploadForm().getSize());
|
||||
log.info("[tusHook] metaData={}", tusHookForm.getTusHookEventForm().getTusHookUploadForm().getMetaData());
|
||||
|
||||
log.info("[tusHookDto] type={}", tusHookForm.tusHookDto().getType());
|
||||
log.info("[tusHookDto] uploadId={}", tusHookForm.tusHookDto().getUploadId());
|
||||
log.info("[tusHookDto] size={}", tusHookForm.tusHookDto().getSize());
|
||||
log.info("[tusHookDto] fileUuid={}", tusHookForm.tusHookDto().getFileUuid());
|
||||
log.info("[tusHookDto] filename={}", tusHookForm.tusHookDto().getFilename());
|
||||
log.info("[tusHookDto] filetype={}", tusHookForm.tusHookDto().getFiletype());
|
||||
|
||||
fileService.saveUploadStatusFromTusHook(tusHookForm.tusHookDto());
|
||||
fileService.updateFileUploadStatus(tusHookForm.tusHookDto());
|
||||
fileService.saveUploadStatusRedisTusHook(tusHookForm.tusHookDto());
|
||||
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_200);
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ public class TusHookDto {
|
||||
private String fileUuid;
|
||||
private String filename;
|
||||
private String filetype;
|
||||
private long uploadedBytes;
|
||||
private int status;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Setter;
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadStatusDto {
|
||||
private String fileMasterKey;
|
||||
private String fileUuid;
|
||||
private String status; // PENDING, UPLOADING, DONE, FAILED
|
||||
private long uploadedBytes;
|
||||
private long totalBytes;
|
||||
|
||||
@@ -9,11 +9,11 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class UploadStatusForm {
|
||||
@NotBlank
|
||||
private String fileMasterKey;
|
||||
private String fileUuid;
|
||||
|
||||
public UploadStatusDto uploadStatusDto() {
|
||||
UploadStatusDto uploadStatusDto = new UploadStatusDto();
|
||||
uploadStatusDto.setFileMasterKey(this.fileMasterKey == null ? null : this.fileMasterKey.trim());
|
||||
uploadStatusDto.setFileUuid(this.fileUuid == null ? null : this.fileUuid.trim());
|
||||
return uploadStatusDto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.alist.api.common.modules.file.mapper;
|
||||
|
||||
import com.alist.api.common.modules.file.dto.FileUploadDto;
|
||||
import com.alist.api.common.modules.file.dto.FileUploadItemDto;
|
||||
import com.alist.api.common.modules.file.dto.UploadStartDto;
|
||||
import com.alist.api.common.modules.file.dto.UploadTokenDto;
|
||||
import com.alist.api.common.modules.file.dto.*;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
@@ -17,4 +14,10 @@ public interface FileMapper {
|
||||
void insertFileDetailInit(FileUploadItemDto item);
|
||||
|
||||
int selectFileDetailCountByFileUuidUserToKenIdx(UploadTokenDto uploadTokenDto);
|
||||
|
||||
void insertFileUploadEventLog(TusHookDto tusHookDto);
|
||||
|
||||
void updateFileDetailStatus(TusHookDto tusHookDto);
|
||||
|
||||
void updateFileMasterAggregateByFileUuid(String fileUuid);
|
||||
}
|
||||
|
||||
@@ -119,40 +119,62 @@ public class FileService {
|
||||
return uploadTokenDto;
|
||||
}
|
||||
|
||||
public UploadStartDto insertFileMasterUpload(Integer userIdx, Integer userTokenIdx, UploadStartDto uploadStartDto) {
|
||||
uploadStartDto.setFileMasterKey(UUID.randomUUID().toString());
|
||||
uploadStartDto.setUserIdx(userIdx);
|
||||
uploadStartDto.setStatus(1);
|
||||
uploadStartDto.setFolderPath(uploadStartDto.getFolderPath() == null ? "/" : uploadStartDto.getFolderPath());
|
||||
|
||||
fileMapper.insertFileMasterUpload(uploadStartDto);
|
||||
|
||||
uploadStartDto.setUploadToken(jwtTokenProvider.createUploadToken(userTokenIdx));
|
||||
uploadStartDto.setTusEndpoint(tusEndpoint);
|
||||
|
||||
return uploadStartDto;
|
||||
}
|
||||
|
||||
public UploadStatusDto getUploadStatus(UploadStatusDto uploadStatusDto) {
|
||||
String key = buildUploadStatusKey(uploadStatusDto.getFileMasterKey());
|
||||
String key = buildUploadStatusKey(uploadStatusDto.getFileUuid());
|
||||
Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
|
||||
|
||||
if (map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UploadStatusDto dto = new UploadStatusDto();
|
||||
dto.setFileMasterKey((String) map.getOrDefault("fileMasterKey", uploadStatusDto.getFileMasterKey()));
|
||||
dto.setStatus((String) map.getOrDefault("status", "PENDING"));
|
||||
dto.setUploadedBytes(parseLong(map.get("uploadedBytes")));
|
||||
dto.setTotalBytes(parseLong(map.get("totalBytes")));
|
||||
dto.setPercent((int) parseLong(map.get("percent")));
|
||||
dto.setUpdatedAt((String) map.getOrDefault("updatedAt", ""));
|
||||
uploadStatusDto.setFileUuid((String) map.getOrDefault("fileUuid", uploadStatusDto.getFileUuid()));
|
||||
uploadStatusDto.setStatus((String) map.getOrDefault("status", "PENDING"));
|
||||
uploadStatusDto.setUploadedBytes(parseLong(map.get("uploadedBytes")));
|
||||
uploadStatusDto.setTotalBytes(parseLong(map.get("totalBytes")));
|
||||
uploadStatusDto.setPercent((int) parseLong(map.get("percent")));
|
||||
uploadStatusDto.setUpdatedAt((String) map.getOrDefault("updatedAt", ""));
|
||||
|
||||
return dto;
|
||||
return uploadStatusDto;
|
||||
}
|
||||
|
||||
public void saveUploadStatusFromTusHook(TusHookDto tusHookDto) {
|
||||
/*db에 상태값 저장*/
|
||||
public void updateFileUploadStatus(TusHookDto tusHookDto) {
|
||||
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String type = tusHookDto.getType() == null ? "" : tusHookDto.getType().trim().toLowerCase();
|
||||
long offset = tusHookDto.getOffset() == null ? 0L : tusHookDto.getOffset();
|
||||
long size = tusHookDto.getSize() == null ? 0L : tusHookDto.getSize();
|
||||
|
||||
fileMapper.insertFileUploadEventLog(tusHookDto);
|
||||
|
||||
tusHookDto.setUploadedBytes(offset);
|
||||
|
||||
switch (type) {
|
||||
case "pre-create", "post-receive":
|
||||
tusHookDto.setStatus(1); // UPLOADING
|
||||
break;
|
||||
case "post-finish":
|
||||
tusHookDto.setStatus(3); // DONE
|
||||
tusHookDto.setUploadedBytes(size);
|
||||
break;
|
||||
case "post-terminate":
|
||||
tusHookDto.setStatus(5); // CANCELED (정책에 따라 FAILED=4)
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
fileMapper.updateFileDetailStatus(tusHookDto);
|
||||
|
||||
if ("post-finish".equals(type) || "post-terminate".equals(type)) {
|
||||
fileMapper.updateFileMasterAggregateByFileUuid(tusHookDto.getFileUuid());
|
||||
}
|
||||
}
|
||||
|
||||
/*레이디스에 상태값 저장*/
|
||||
public void saveUploadStatusRedisTusHook(TusHookDto tusHookDto) {
|
||||
if (tusHookDto == null || tusHookDto.getFileUuid() == null || tusHookDto.getFileUuid().isBlank()) {
|
||||
return;
|
||||
}
|
||||
@@ -186,10 +208,6 @@ public class FileService {
|
||||
stringRedisTemplate.expire(key, Duration.ofHours(24));
|
||||
}
|
||||
|
||||
public void insertFileAndSave(TusHookDto tusHookDto) {
|
||||
|
||||
}
|
||||
|
||||
private String buildUploadStatusKey(String fileUuid) {
|
||||
return "upload:alist:status:" + fileUuid;
|
||||
}
|
||||
@@ -217,7 +235,7 @@ public class FileService {
|
||||
}
|
||||
}
|
||||
|
||||
private void evictUploadAuthCacheByFileMasterKey(String fileUuid) {
|
||||
private void evictUploadAuthCacheByFileUuid(String fileUuid) {
|
||||
try {
|
||||
String pattern = "upload:alist:auth:" + fileUuid + ":*";
|
||||
var keys = stringRedisTemplate.keys(pattern);
|
||||
|
||||
@@ -24,12 +24,80 @@
|
||||
<insert id="insertFileMasterUpload">
|
||||
/*FileMapper.insertFileMasterUpload*/
|
||||
INSERT INTO ALISTLMS.FILE_MASTER2 (
|
||||
FILE_MASTER_KEY, USER_IDX, FILE_CATEGORY, FOLDER_PATH, STATUS, CREATE_MEMBER, UPDATE_MEMBER
|
||||
FILE_MASTER_KEY, USER_IDX, FILE_CATEGORY, FOLDER_PATH, STATUS, CREATE_MEMBER, UPDATE_MEMBER
|
||||
) values (
|
||||
#{fileMasterKey}, #{userIdx}, #{fileCategory}, #{folderPath}, #{status}, #{userIdx}, #{userIdx}
|
||||
#{fileMasterKey}, #{userIdx}, #{fileCategory}, #{folderPath}, #{status}, #{userIdx}, #{userIdx}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="insertFileUploadEventLog">
|
||||
/*FileMapper.insertFileUploadEventLog*/
|
||||
INSERT INTO ALISTLMS.FILE_UPLOAD_EVENT_LOG (
|
||||
FILE_DETAIL_IDX, EVENT_TYPE, OFFSET_BYTES, BYTES_WRITTEN, HTTP_STATUS, MESSAGE, RAW_JSON
|
||||
)
|
||||
SELECT
|
||||
LFD.FILE_DETAIL_IDX
|
||||
, #{type}
|
||||
, #{offset}
|
||||
, NULL
|
||||
, NULL
|
||||
, NULL
|
||||
, NULL
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
WHERE LFD.FILE_UUID = #{fileUuid}
|
||||
LIMIT 1
|
||||
</insert>
|
||||
|
||||
<update id="updateFileDetailStatus">
|
||||
/*FileMapper.updateFileDetailStatus*/
|
||||
UPDATE ALISTLMS.FILE_DETAIL
|
||||
<set>
|
||||
<if test="uploadId != null and uploadId != ''">
|
||||
TUS_UPLOAD_ID = #{uploadId},
|
||||
</if>
|
||||
<if test="uploadedBytes != null">
|
||||
UPLOADED_BYTES = #{uploadedBytes},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
STATUS = #{status},
|
||||
</if>
|
||||
UPDATE_DATE = NOW()
|
||||
</set>
|
||||
WHERE FILE_UUID = #{fileUuid}
|
||||
AND DEL_YN = 'N'
|
||||
</update>
|
||||
|
||||
<update id="updateFileMasterAggregateByFileUuid">
|
||||
/*FileMapper.updateFileMasterAggregateByFileUuid*/
|
||||
UPDATE ALISTLMS.FILE_MASTER LFM
|
||||
JOIN (
|
||||
SELECT
|
||||
LLFD.FILE_MASTER_IDX,
|
||||
COUNT(*) AS total_count,
|
||||
SUM(CASE WHEN LLFD.STATUS = 3 THEN 1 ELSE 0 END) AS done_count,
|
||||
SUM(CASE WHEN LLFD.STATUS IN (4,5) THEN 1 ELSE 0 END) AS fail_count
|
||||
FROM ALISTLMS.FILE_DETAIL LLFD
|
||||
WHERE LLFD.FILE_MASTER_IDX = (
|
||||
SELECT FILE_MASTER_IDX
|
||||
FROM ALISTLMS.FILE_DETAIL
|
||||
WHERE FILE_UUID = #{fileUuid}
|
||||
LIMIT 1
|
||||
)
|
||||
AND LLFD.DEL_YN = 'N'
|
||||
) A ON A.FILE_MASTER_IDX = LFM.FILE_MASTER_IDX
|
||||
SET LFM.TOTAL_COUNT = A.total_count,
|
||||
LFM.DONE_COUNT = A.done_count,
|
||||
LFM.FAIL_COUNT = A.fail_count,
|
||||
LFM.STATUS = CASE
|
||||
WHEN A.done_count = A.total_count THEN 3
|
||||
WHEN A.done_count = 0 AND A.fail_count = A.total_count THEN 4
|
||||
WHEN A.done_count > 0 AND A.fail_count > 0 THEN 5
|
||||
ELSE 1
|
||||
END,
|
||||
LFM.UPDATE_DATE = NOW()
|
||||
</update>
|
||||
|
||||
|
||||
<select id="selectFileMasterCountByFileMasterKeyAndDelYnAndStatus" resultType="int">
|
||||
/*FileMapper.selectFileMasterCountByFileMasterKeyAndDelYnAndStatus*/
|
||||
SELECT COUNT(*)
|
||||
|
||||
Reference in New Issue
Block a user