From bc3ad7b9ddba89f51b2b190c1a3f25944c3bf65b Mon Sep 17 00:00:00 2001 From: Sonia Zorba Date: Wed, 3 Feb 2021 10:49:50 +0100 Subject: [PATCH] Handled duplicate files upload and other edge cases --- .../controller/GetFileController.java | 4 +- .../controller/PutFileController.java | 47 ++++++++++++++++++- .../ia2/transfer/persistence/FileDAO.java | 26 ++++++++++ .../controller/GetFileControllerTest.java | 4 ++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/main/java/it/inaf/ia2/transfer/controller/GetFileController.java b/src/main/java/it/inaf/ia2/transfer/controller/GetFileController.java index 4a24771..b4a3a16 100644 --- a/src/main/java/it/inaf/ia2/transfer/controller/GetFileController.java +++ b/src/main/java/it/inaf/ia2/transfer/controller/GetFileController.java @@ -98,7 +98,9 @@ public class GetFileController { return new ResponseEntity<>("File " + file.getName() + " is not readable", INTERNAL_SERVER_ERROR); } - response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); + String vosName = fileInfo.getVirtualPath().substring(fileInfo.getVirtualPath().lastIndexOf("/") + 1); + + response.setHeader("Content-Disposition", "attachment; filename=" + vosName); response.setHeader("Content-Length", String.valueOf(file.length())); byte[] bytes = new byte[1024]; diff --git a/src/main/java/it/inaf/ia2/transfer/controller/PutFileController.java b/src/main/java/it/inaf/ia2/transfer/controller/PutFileController.java index 08a984f..4c9c724 100644 --- a/src/main/java/it/inaf/ia2/transfer/controller/PutFileController.java +++ b/src/main/java/it/inaf/ia2/transfer/controller/PutFileController.java @@ -89,6 +89,51 @@ public class PutFileController { } } - Files.copy(is, file.toPath()); + String originalFileName = file.getName(); + file = getEmptyFile(file, 1); + if (!originalFileName.equals(file.getName())) { + fileDAO.setOsName(fileInfo.getNodeId(), file.getName()); + } + + try { + fileDAO.setBusy(fileInfo.getNodeId(), true); + Files.copy(is, file.toPath()); + } catch (IOException ex) { + throw ex; + } finally { + fileDAO.setBusy(fileInfo.getNodeId(), false); + } + } + + /** + * Handles duplicate file uploads generating a new non existent path. This + * is necessary in some edge cases, like when a file has been renamed in + * VOSpace only but the original file on disk still has the old name or if a + * file has been marked for deletion and a file with the same name is + * uploaded before the cleanup. + */ + private File getEmptyFile(File file, int index) { + if (file.exists()) { + + String fileName = file.getName(); + + String nameWithoutExtension; + String extension = null; + if (fileName.contains(".")) { + nameWithoutExtension = fileName.substring(0, fileName.lastIndexOf(".")); + extension = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); + } else { + nameWithoutExtension = fileName; + } + + String newName = nameWithoutExtension + "-" + index; + if (extension != null) { + newName += "." + extension; + } + + File newFile = file.toPath().getParent().resolve(newName).toFile(); + return getEmptyFile(newFile, index + 1); + } + return file; } } diff --git a/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java b/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java index 762f0dd..8bb43f7 100644 --- a/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java +++ b/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java @@ -84,6 +84,8 @@ public class FileDAO { if (asyncLocation) { String username = rs.getString("username"); completeOsPath = completeOsPath.resolve(username).resolve("retrieve"); + } else { + completeOsPath = completeOsPath.resolve(fi.getOwnerId()); } completeOsPath = completeOsPath.resolve(osPath); @@ -96,4 +98,28 @@ public class FileDAO { } return Arrays.asList((String[]) array.getArray()); } + + public void setBusy(int nodeId, boolean busy) { + + String sql = "UPDATE node SET busy_state = ? WHERE node_id = ?"; + + jdbcTemplate.update(conn -> { + PreparedStatement ps = conn.prepareStatement(sql); + ps.setBoolean(1, busy); + ps.setInt(2, nodeId); + return ps; + }); + } + + public void setOsName(int nodeId, String newName) { + + String sql = "UPDATE node SET os_name = ? WHERE node_id = ?"; + + jdbcTemplate.update(conn -> { + PreparedStatement ps = conn.prepareStatement(sql); + ps.setString(1, newName); + ps.setInt(2, nodeId); + return ps; + }); + } } diff --git a/src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java b/src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java index 37fbc8f..9428c0e 100644 --- a/src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java +++ b/src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java @@ -58,6 +58,7 @@ public class GetFileControllerTest { FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); + fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setIsPublic(true); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); @@ -124,6 +125,7 @@ public class GetFileControllerTest { FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); + fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setGroupRead(Collections.singletonList("group1")); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); @@ -138,6 +140,7 @@ public class GetFileControllerTest { when(tokenParser.getClaims(any())).thenReturn(claims); FileInfo fileInfo = new FileInfo(); + fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setOwnerId("123"); @@ -153,6 +156,7 @@ public class GetFileControllerTest { public void testPrivateFileNullToken() throws Exception { FileInfo fileInfo = new FileInfo(); + fileInfo.setVirtualPath("/path/to/myfile"); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); -- GitLab