Skip to content

Commit

Permalink
merge branch 'main' into hot-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
seungh1024 committed Aug 26, 2024
2 parents 8df74b8 + b775174 commit 1a18d3d
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,8 @@ public void cancelShare() {
this.permissionType = PermissionType.NONE;
this.sharingExpiredAt = CommonConstant.UNAVAILABLE_TIME;
}

public boolean isSharingExpired() {
return sharingExpiredAt.isBefore(LocalDateTime.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.woowacamp.storage.domain.file.event;

import org.springframework.context.ApplicationEvent;

import com.woowacamp.storage.domain.file.entity.FileMetadata;
import com.woowacamp.storage.domain.folder.entity.FolderMetadata;

import lombok.Getter;

@Getter
public class FileMoveEvent extends ApplicationEvent {
private final FileMetadata sourceFile;
private final FolderMetadata targetFolder;

public FileMoveEvent(Object source, FileMetadata sourceFile, FolderMetadata targetFolder) {
super(source);
this.sourceFile = sourceFile;
this.targetFolder = targetFolder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.woowacamp.storage.domain.file.event;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import com.woowacamp.storage.domain.shredlink.service.SharedLinkService;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class FileMoveEventListener {
private final SharedLinkService sharingService;

@EventListener
public void updateSubSharingStatus(FileMoveEvent moveEvent) {
sharingService.updateFileShareStatus(moveEvent.getSourceFile().getId(),
moveEvent.getTargetFolder().getPermissionType(), moveEvent.getTargetFolder().getSharingExpiredAt());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import static com.woowacamp.storage.global.error.ErrorCode.*;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Set;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -14,6 +16,7 @@
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.woowacamp.storage.domain.file.dto.FileMoveDto;
import com.woowacamp.storage.domain.file.entity.FileMetadata;
import com.woowacamp.storage.domain.file.event.FileMoveEvent;
import com.woowacamp.storage.domain.file.repository.FileMetadataRepository;
import com.woowacamp.storage.domain.folder.entity.FolderMetadata;
import com.woowacamp.storage.domain.folder.repository.FolderMetadataRepository;
Expand All @@ -31,6 +34,7 @@ public class FileService {
private final FolderMetadataRepository folderMetadataRepository;
private final FolderSearchUtil folderSearchUtil;
private final AmazonS3 amazonS3;
private final ApplicationEventPublisher eventPublisher;
@Value("${cloud.aws.credentials.bucketName}")
private String BUCKET_NAME;

Expand All @@ -54,6 +58,8 @@ public void moveFile(Long fileId, FileMoveDto dto) {
FolderMetadata commonAncestor = folderSearchUtil.getCommonAncestor(sourcePath, targetPath);
folderSearchUtil.updateFolderPath(sourcePath, targetPath, commonAncestor, fileMetadata.getFileSize());
fileMetadata.updateParentFolderId(dto.targetFolderId());

eventPublisher.publishEvent(new FileMoveEvent(this, fileMetadata, folderMetadata));
}

private void validateMetadata(FileMoveDto dto, FileMetadata fileMetadata) {
Expand Down Expand Up @@ -90,6 +96,17 @@ public void deleteFile(Long fileId, Long userId) {
} catch (AmazonS3Exception e) {
throw ErrorCode.FILE_DELETE_FAILED.baseException();
}

Long currentFolderId = fileMetadata.getParentFolderId();
long fileSize = fileMetadata.getFileSize();
LocalDateTime now = LocalDateTime.now();
while (currentFolderId != null) {
FolderMetadata currentFolderMetadata = folderMetadataRepository.findByIdForUpdate(currentFolderId)
.orElseThrow(ErrorCode.FOLDER_NOT_FOUND::baseException);
currentFolderMetadata.addSize(-fileSize);
currentFolderMetadata.updateUpdatedAt(now);
currentFolderId = currentFolderMetadata.getParentFolderId();
}
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.woowacamp.storage.domain.folder.controller;

import java.util.Objects;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -53,7 +55,8 @@ public FolderContentsDto getFolderContents(@CheckField(value = FieldType.FOLDER_
folderService.checkFolderOwnedBy(folderId, request.userId());

return folderService.getFolderContents(folderId, request.cursorId(), request.cursorType(), request.limit(),
request.sortBy(), request.sortDirection(), request.localDateTime(), request.size());
request.sortBy(), request.sortDirection(), request.localDateTime(), request.size(),
Objects.equals(request.userId(), request.creatorId()));
}

@RequestType(permission = PermissionType.WRITE, fileType = FileType.FOLDER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
public record GetFolderContentsRequestParams(@NotNull @Positive @CheckField(value = FieldType.USER_ID) Long userId,
@NotNull @Positive Long cursorId, @NotNull CursorType cursorType,
@Positive @Max(MAX_SIZE) Integer limit, FolderContentsSortField sortBy,
Sort.Direction sortDirection, LocalDateTime localDateTime, Long size) {
Sort.Direction sortDirection, LocalDateTime localDateTime, Long size,
@CheckField(FieldType.CREATOR_ID) Long creatorId) {
private static final int MAX_SIZE = 1000;
private static final int DEFAULT_SIZE = 100;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,8 @@ public void cancelShare() {
this.permissionType = PermissionType.NONE;
this.sharingExpiredAt = CommonConstant.UNAVAILABLE_TIME;
}

public boolean isSharingExpired() {
return sharingExpiredAt.isBefore(LocalDateTime.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.woowacamp.storage.domain.folder.event;

import org.springframework.context.ApplicationEvent;

import com.woowacamp.storage.domain.folder.entity.FolderMetadata;

import lombok.Getter;

@Getter
public class FolderMoveEvent extends ApplicationEvent {
private final FolderMetadata sourceFolder;
private final FolderMetadata targetFolder;

public FolderMoveEvent(Object source, FolderMetadata sourceFolder, FolderMetadata targetFolder) {
super(source);
this.sourceFolder = sourceFolder;
this.targetFolder = targetFolder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.woowacamp.storage.domain.folder.event;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import com.woowacamp.storage.domain.shredlink.service.SharedLinkService;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class FolderMoveEventListener {
private final SharedLinkService sharingService;

@EventListener
public void updateSubSharingStatus(FolderMoveEvent moveEvent) {
sharingService.updateFolderSharingStatus(moveEvent.getSourceFolder().getId(),
moveEvent.getTargetFolder().getPermissionType(), moveEvent.getTargetFolder().getSharingExpiredAt());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.Stack;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
Expand All @@ -29,6 +30,7 @@
import com.woowacamp.storage.domain.folder.dto.request.CreateFolderReqDto;
import com.woowacamp.storage.domain.folder.dto.request.FolderMoveDto;
import com.woowacamp.storage.domain.folder.entity.FolderMetadata;
import com.woowacamp.storage.domain.folder.event.FolderMoveEvent;
import com.woowacamp.storage.domain.folder.repository.FolderMetadataRepository;
import com.woowacamp.storage.domain.folder.utils.FolderSearchUtil;
import com.woowacamp.storage.domain.user.entity.User;
Expand All @@ -48,6 +50,7 @@ public class FolderService {
private final UserRepository userRepository;
private final FolderSearchUtil folderSearchUtil;
private final AmazonS3 amazonS3;
private final ApplicationEventPublisher eventPublisher;
@Value("${cloud.aws.credentials.bucketName}")
private String BUCKET_NAME;

Expand All @@ -63,17 +66,18 @@ public void checkFolderOwnedBy(long folderId, long userId) {

@Transactional(readOnly = true)
public FolderContentsDto getFolderContents(Long folderId, Long cursorId, CursorType cursorType, int limit,
FolderContentsSortField sortBy, Sort.Direction sortDirection, LocalDateTime dateTime, Long size) {
FolderContentsSortField sortBy, Sort.Direction sortDirection, LocalDateTime dateTime, Long size,
boolean ownerRequested) {
List<FolderMetadata> folders = new ArrayList<>();
List<FileMetadata> files = new ArrayList<>();

if (cursorType.equals(CursorType.FILE)) {
files = fetchFiles(folderId, cursorId, limit, sortBy, sortDirection, dateTime, size);
files = fetchFiles(folderId, cursorId, limit, sortBy, sortDirection, dateTime, size, ownerRequested);
} else if (cursorType.equals(CursorType.FOLDER)) {
folders = fetchFolders(folderId, cursorId, limit, sortBy, sortDirection, dateTime, size);
folders = fetchFolders(folderId, cursorId, limit, sortBy, sortDirection, dateTime, size, ownerRequested);
if (folders.size() < limit) {
files = fetchFiles(folderId, INITIAL_CURSOR_ID, limit - folders.size(), sortBy, sortDirection, dateTime,
size);
size, ownerRequested);
}
}

Expand All @@ -91,6 +95,9 @@ public void moveFolder(Long sourceFolderId, FolderMoveDto dto) {
FolderMetadata commonAncestor = folderSearchUtil.getCommonAncestor(sourcePath, targetPath);
folderSearchUtil.updateFolderPath(sourcePath, targetPath, commonAncestor, folderMetadata.getSize());
folderMetadata.updateParentFolderId(dto.targetFolderId());

eventPublisher.publishEvent(
new FolderMoveEvent(this, folderMetadata, folderMetadataRepository.findById(dto.targetFolderId()).get()));
}

private void validateMoveFolder(Long sourceFolderId, FolderMoveDto dto, FolderMetadata folderMetadata) {
Expand Down Expand Up @@ -163,15 +170,23 @@ private void validateDuplicatedFolderName(FolderMoveDto dto, FolderMetadata fold
}

private List<FileMetadata> fetchFiles(Long folderId, Long cursorId, int limit, FolderContentsSortField sortBy,
Sort.Direction direction, LocalDateTime dateTime, Long size) {
return fileMetadataRepository.selectFilesWithPagination(folderId, cursorId, sortBy, direction, limit, dateTime,
size);
Sort.Direction direction, LocalDateTime dateTime, Long size, boolean ownerRequested) {
List<FileMetadata> files = fileMetadataRepository.selectFilesWithPagination(folderId, cursorId, sortBy,
direction, limit, dateTime, size);
if (!ownerRequested) {
files = files.stream().filter(file -> !file.isSharingExpired()).toList();
}
return files;
}

private List<FolderMetadata> fetchFolders(Long folderId, Long cursorId, int limit, FolderContentsSortField sortBy,
Sort.Direction direction, LocalDateTime dateTime, Long size) {
return folderMetadataRepository.selectFoldersWithPagination(folderId, cursorId, sortBy, direction, limit,
dateTime, size);
Sort.Direction direction, LocalDateTime dateTime, Long size, boolean ownerRequested) {
List<FolderMetadata> folders = folderMetadataRepository.selectFoldersWithPagination(folderId, cursorId,
sortBy, direction, limit, dateTime, size);
if (!ownerRequested) {
folders = folders.stream().filter(folder -> !folder.isSharingExpired()).toList();
}
return folders;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class SharedLinkFactory {
public static SharedLink createSharedLink(MakeSharedLinkRequestDto requestDto, String sharedId,
String redirectUrl) {
LocalDateTime createTime = LocalDateTime.now();
LocalDateTime expiredTime = createTime.plusSeconds(CommonConstant.SHARED_LINK_VALID_TIME);
LocalDateTime expiredTime = createTime.plusHours(CommonConstant.SHARED_LINK_VALID_TIME);
return SharedLink.builder()
.createdAt(createTime)
.redirectUrl(redirectUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void updateShareStatus(SharedLink sharedLink) {
updateFileShareStatus(sharedLink.getTargetId(), sharedLink.getPermissionType(),
sharedLink.getExpiredAt());
} else {
updateSubFolderShareStatus(sharedLink.getTargetId(),
updateFolderSharingStatus(sharedLink.getTargetId(),
sharedLink.getPermissionType(), sharedLink.getExpiredAt());
}
}
Expand All @@ -134,11 +134,10 @@ public void updateFileShareStatus(Long fileId, PermissionType permissionType, Lo
fileMetadata.updateShareStatus(permissionType, sharingExpireAt);
}

public void updateSubFolderShareStatus(Long folderId, PermissionType permissionType,
public void updateFolderSharingStatus(Long folderId, PermissionType permissionType,
LocalDateTime sharingExpireAt) {
FolderMetadata folder = folderMetadataRepository.findById(folderId)
folderMetadataRepository.findById(folderId)
.orElseThrow(ErrorCode.FILE_NOT_FOUND::baseException);
folder.cancelShare();

Stack<Long> folderIdStack = new Stack<>();
folderIdStack.push(folderId);
Expand Down Expand Up @@ -194,7 +193,6 @@ private void cancelShare(boolean isFile, Long targetId) {
public void cancelFolderShare(Long folderId) {
FolderMetadata folder = folderMetadataRepository.findById(folderId)
.orElseThrow(ErrorCode.FILE_NOT_FOUND::baseException);
folder.cancelShare();

Stack<Long> folderIdStack = new Stack<>();
folderIdStack.push(folderId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,20 @@ class WithFileCursorType {
void orderByCreatedAt_asc() {
// When
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FILE,
10, FolderContentsSortField.CREATED_AT, Sort.Direction.ASC, now.minusDays(7), 0L);
10, FolderContentsSortField.CREATED_AT, Sort.Direction.ASC, now.minusDays(7), 0L, true);

// Then
assertEquals(7, result.fileMetadataList().size());
assertTrue(result.folderMetadataList().isEmpty());
for (int i = 0; i < result.fileMetadataList().size() - 1; i++) {
assertTrue(result.fileMetadataList()
.get(i)
.getCreatedAt()
.isBefore(result.fileMetadataList().get(i + 1).getCreatedAt())
|| result.fileMetadataList()
.get(i)
.getCreatedAt()
.equals(result.fileMetadataList().get(i + 1).getCreatedAt()));
.get(i)
.getCreatedAt()
.isBefore(result.fileMetadataList().get(i + 1).getCreatedAt())
|| result.fileMetadataList()
.get(i)
.getCreatedAt()
.equals(result.fileMetadataList().get(i + 1).getCreatedAt()));
}
}

Expand All @@ -127,7 +127,7 @@ void orderByCreatedAt_asc() {
void orderBySize_desc() {
// When
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FILE,
10, FolderContentsSortField.DATA_SIZE, Sort.Direction.ASC, now, 0L);
10, FolderContentsSortField.DATA_SIZE, Sort.Direction.ASC, now, 0L, true);

// Then
assertEquals(7, result.fileMetadataList().size());
Expand All @@ -140,7 +140,7 @@ void withLimit() {
// When
int limit = 5;
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FILE,
limit, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L);
limit, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L, true);

// Then
assertEquals(limit, result.fileMetadataList().size());
Expand All @@ -157,7 +157,7 @@ class WithFolderCursorType {
void orderByCreatedAt_desc() {
// When
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FOLDER,
20, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L);
20, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L, true);

// Then
List<FolderMetadata> resultFolders = result.folderMetadataList();
Expand All @@ -166,11 +166,11 @@ void orderByCreatedAt_desc() {
assertEquals(7, resultFiles.size());
for (int i = 0; i < resultFolders.size() - 1; i++) {
assertTrue(resultFolders.get(i).getCreatedAt().isAfter(resultFolders.get(i + 1).getCreatedAt())
|| resultFolders.get(i).getCreatedAt().equals(resultFolders.get(i + 1).getCreatedAt()));
|| resultFolders.get(i).getCreatedAt().equals(resultFolders.get(i + 1).getCreatedAt()));
}
for (int i = 0; i < resultFiles.size() - 1; i++) {
assertTrue(resultFiles.get(i).getCreatedAt().isAfter(resultFiles.get(i + 1).getCreatedAt())
|| resultFiles.get(i).getCreatedAt().equals(resultFiles.get(i + 1).getCreatedAt()));
|| resultFiles.get(i).getCreatedAt().equals(resultFiles.get(i + 1).getCreatedAt()));
}
}

Expand All @@ -179,7 +179,7 @@ void orderByCreatedAt_desc() {
void orderBySize_asc() {
// When
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FOLDER,
20, FolderContentsSortField.DATA_SIZE, Sort.Direction.ASC, now, 0L);
20, FolderContentsSortField.DATA_SIZE, Sort.Direction.ASC, now, 0L, true);

// Then
List<FolderMetadata> resultFolders = result.folderMetadataList();
Expand All @@ -200,7 +200,7 @@ void withLimit() {
// When
int limit = 10;
FolderContentsDto result = folderService.getFolderContents(parentFolder.getId(), 0L, CursorType.FOLDER,
limit, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L);
limit, FolderContentsSortField.CREATED_AT, Sort.Direction.DESC, now, 0L, true);

// Then
assertEquals(limit, result.folderMetadataList().size() + result.fileMetadataList().size());
Expand Down

0 comments on commit 1a18d3d

Please sign in to comment.