From 209bdccfdf6cf03524a712b91cc0d7a956747e60 Mon Sep 17 00:00:00 2001 From: Sonia Zorba <sonia.zorba@inaf.it> Date: Fri, 10 Sep 2021 16:49:08 +0200 Subject: [PATCH] Added location type to FileInfo and fixed issue with generation of archives containing async nodes --- .../ia2/transfer/persistence/FileDAO.java | 29 +++++++-------- .../transfer/persistence/model/FileInfo.java | 15 ++++++-- .../ia2/transfer/service/ArchiveService.java | 2 +- .../ia2/transfer/service/FileCopyService.java | 36 +++++++++---------- .../ia2/transfer/persistence/FileDAOTest.java | 4 +++ 5 files changed, 50 insertions(+), 36 deletions(-) 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 7a54147..0c006a6 100644 --- a/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java +++ b/src/main/java/it/inaf/ia2/transfer/persistence/FileDAO.java @@ -94,7 +94,7 @@ public class FileDAO { // This should never happen thanks to database constraints throw new IllegalStateException("More than one node at path: " + vosPath); } - + return nodes; } @@ -175,8 +175,8 @@ public class FileDAO { + "n.accept_views, n.provide_views, l.location_type, n.path <> n.relative_path AS virtual_parent,\n" + "(SELECT user_name FROM users WHERE user_id = n.creator_id) AS username,\n" + "base_path, get_os_path(n.node_id) AS os_path, get_vos_path(n.node_id) AS vos_path,\n" - + "n.type = 'container' AS is_directory, n.name, n.location_id, n.job_id\n" - + "n.type = 'link' AS is_link\n" + + "n.type = 'container' AS is_directory, n.name, n.location_id, n.job_id,\n" + + "n.type = 'link' AS is_link, l.location_type\n" + "FROM node n\n" + "JOIN node p ON p.path @> n.path\n" + "LEFT JOIN location l ON l.location_id = n.location_id\n" @@ -200,16 +200,16 @@ public class FileDAO { }); } - // TODO: same problem as get archive file infos + // TODO: same problem as get archive file infos public List<FileInfo> getBranchFileInfos(String rootVosPath, String jobId) { - + String sql = "SELECT n.node_id, n.is_public, n.group_read, n.group_write, n.creator_id, n.async_trans,\n" + "n.content_type, n.content_encoding, n.content_length, n.content_md5,\n" + "n.accept_views, n.provide_views, l.location_type, n.path <> n.relative_path AS virtual_parent,\n" + "(SELECT user_name FROM users WHERE user_id = n.creator_id) AS username,\n" + "base_path, get_os_path(n.node_id) AS os_path, get_vos_path(n.node_id) AS vos_path,\n" + "n.type = 'container' AS is_directory, n.name, n.location_id, n.job_id,\n" - + "n.type = 'link' AS is_link\n" + + "n.type = 'link' AS is_link, l.location_type\n" + "FROM node n\n" + "JOIN node p ON p.path @> n.path\n" + "LEFT JOIN location l ON l.location_id = n.location_id\n" @@ -232,17 +232,17 @@ public class FileDAO { } public void setBranchLocationId(String rootVosPath, String jobId, int locationId) { - + String cte = "SELECT n.node_id AS id\n" + "FROM node n\n" + "JOIN node p ON p.path @> n.path\n" + "WHERE (p.node_id = id_from_vos_path(?) AND n.job_id = ?)\n"; - + String update = "UPDATE node\n" + " SET location_id = ?\n" + "FROM cte\n" + "WHERE node_id = cte.id\n"; - + String sql = "WITH cte AS (\n" + cte + ")\n" @@ -256,16 +256,16 @@ public class FileDAO { return ps; }); } - + // !! duplicate code from NodeDAO public void releaseBusyNodesByJobId(String jobId) { String sql = "UPDATE node SET job_id = NULL WHERE job_id = ?"; - + jdbcTemplate.update(conn -> { PreparedStatement ps = conn.prepareStatement(sql); - ps.setString(1, jobId); + ps.setString(1, jobId); return ps; - }); + }); } private FileInfo getFileInfo(ResultSet rs) throws SQLException { @@ -290,10 +290,11 @@ public class FileDAO { fi.setContentType(rs.getString("content_type")); fi.setDirectory(rs.getBoolean("is_directory")); fi.setLink(rs.getBoolean("is_link")); - fi.setJobId(rs.getString("job_id")); + fi.setJobId(rs.getString("job_id")); int locationId = rs.getInt("location_id"); if (!rs.wasNull()) { fi.setLocationId(locationId); + fi.setLocationType(rs.getString("location_type")); } fillOsPath(fi, rs); diff --git a/src/main/java/it/inaf/ia2/transfer/persistence/model/FileInfo.java b/src/main/java/it/inaf/ia2/transfer/persistence/model/FileInfo.java index 49f859e..7396e6c 100644 --- a/src/main/java/it/inaf/ia2/transfer/persistence/model/FileInfo.java +++ b/src/main/java/it/inaf/ia2/transfer/persistence/model/FileInfo.java @@ -28,6 +28,7 @@ public class FileInfo { private Long contentLength; private String contentMd5; private Integer locationId; + private String locationType; private String jobId; public int getNodeId() { @@ -109,7 +110,7 @@ public class FileInfo { public void setDirectory(boolean directory) { this.directory = directory; } - + public boolean isLink() { return link; } @@ -182,6 +183,14 @@ public class FileInfo { this.locationId = locationId; } + public String getLocationType() { + return locationType; + } + + public void setLocationType(String locationType) { + this.locationType = locationType; + } + public String getJobId() { return jobId; } @@ -189,8 +198,8 @@ public class FileInfo { public void setJobId(String jobId) { this.jobId = jobId; } - + public static String getVosParentPath(FileInfo fileInfo) { - return fileInfo.getVirtualPath().substring(0, fileInfo.getVirtualPath().lastIndexOf("/")); + return fileInfo.getVirtualPath().substring(0, fileInfo.getVirtualPath().lastIndexOf("/")); } } diff --git a/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java b/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java index 74a1fd1..f124493 100644 --- a/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java +++ b/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java @@ -112,7 +112,7 @@ public class ArchiveService { continue; } - if (fileInfo.getLocationId() != null && fileInfo.getLocationId() != uploadLocationId) { + if (fileInfo.getLocationId() != null && "portal".equals(fileInfo.getLocationType())) { // remote file if (portalLocationUrls == null) { portalLocationUrls = locationDAO.getPortalLocationUrls(); diff --git a/src/main/java/it/inaf/ia2/transfer/service/FileCopyService.java b/src/main/java/it/inaf/ia2/transfer/service/FileCopyService.java index b18e684..23b565a 100644 --- a/src/main/java/it/inaf/ia2/transfer/service/FileCopyService.java +++ b/src/main/java/it/inaf/ia2/transfer/service/FileCopyService.java @@ -43,32 +43,32 @@ public class FileCopyService { @Autowired private RestTemplate restTemplate; - + @Autowired private PutFileService putFileService; - + @Value("${upload_location_id}") private int uploadLocationId; public void copyFiles(String sourceRootVosPath, String destinationRootVosPath, String jobId, TokenPrincipal principal) { - - LOG.trace("copyFiles called for source {}, destination {}, from jobId \"{}\"", + + LOG.trace("copyFiles called for source {}, destination {}, from jobId \"{}\"", sourceRootVosPath, destinationRootVosPath, jobId); // We use jobId to identify nodes created by the REST part of CopyNode // We expect them to be locked List<FileInfo> sources = fileDAO.getBranchFileInfos(sourceRootVosPath, jobId); - + LOG.debug("found {} sources", sources.size()); if (sources.isEmpty()) { throw new NodeNotFoundException(sourceRootVosPath); } - - - // Set location of destinations to this file service update location + + + // Set location of destinations to this file service update location // before retrieving file infos fileDAO.setBranchLocationId(destinationRootVosPath, jobId, uploadLocationId); @@ -76,7 +76,7 @@ public class FileCopyService { = fileDAO.getBranchFileInfos(destinationRootVosPath, jobId); LOG.debug("found {} destinations", destinations.size()); - + if (destinations.isEmpty()) { throw new NodeNotFoundException(destinationRootVosPath); } @@ -94,7 +94,7 @@ public class FileCopyService { principal); } - + private void fillDestinations(List<FileInfo> sourcesFileInfos, List<FileInfo> destinationFileInfos, String sourceRootVosPath, @@ -102,7 +102,7 @@ public class FileCopyService { TokenPrincipal principal) { // it will be initialized only when necessary - Map<Integer, String> portalLocationUrls = null; + Map<Integer, String> portalLocationUrls = null; for (FileInfo destinationFileInfo : destinationFileInfos) { LOG.trace("Processing {} destination", destinationFileInfo.getVirtualPath()); @@ -134,25 +134,25 @@ public class FileCopyService { } } - if (sourceFileInfo.getLocationId() != null && sourceFileInfo.getLocationId() != uploadLocationId) { + if (sourceFileInfo.getLocationId() != null && "portal".equals(sourceFileInfo.getLocationType())) { // remote file if (portalLocationUrls == null) { portalLocationUrls = locationDAO.getPortalLocationUrls(); } String url = portalLocationUrls.get(sourceFileInfo.getLocationId()); // download file to destination disk path - this.downloadFileToDisk(sourceFileInfo, - destinationFileInfo, + this.downloadFileToDisk(sourceFileInfo, + destinationFileInfo, principal, url, remainingQuota); } else { - // local file + // local file this.copyLocalFile(sourceFileInfo, destinationFileInfo, principal, remainingQuota); } } - } + } } private String getCorrespondingSourceVosPath(String sourceRootVosPath, @@ -200,7 +200,7 @@ public class FileCopyService { private void copyLocalFile(FileInfo sourceFileInfo, FileInfo destinationFileInfo, TokenPrincipal tokenPrincipal, Long remainingQuota) { - + // Check permission if (!authorizationService.isDownloadable(sourceFileInfo, tokenPrincipal)) { throw PermissionDeniedException.forPath(sourceFileInfo.getVirtualPath()); @@ -208,7 +208,7 @@ public class FileCopyService { File file = new File(sourceFileInfo.getOsPath()); LOG.trace("Copying file: {} to {}",file.getAbsolutePath(), destinationFileInfo.getOsPath()); - + putFileService.copyLocalFile(sourceFileInfo, destinationFileInfo, remainingQuota); } diff --git a/src/test/java/it/inaf/ia2/transfer/persistence/FileDAOTest.java b/src/test/java/it/inaf/ia2/transfer/persistence/FileDAOTest.java index 622f5dd..b8336a0 100644 --- a/src/test/java/it/inaf/ia2/transfer/persistence/FileDAOTest.java +++ b/src/test/java/it/inaf/ia2/transfer/persistence/FileDAOTest.java @@ -88,10 +88,14 @@ public class FileDAOTest { assertEquals("/home/vospace/upload/user1/file1", fileInfos.get(0).getOsPath()); assertEquals("/home/vospace/upload/user1/file2", fileInfos.get(1).getOsPath()); + assertEquals("user", fileInfos.get(1).getLocationType()); assertTrue(fileInfos.get(2).isDirectory()); + assertNull(fileInfos.get(2).getLocationType()); assertEquals("/home/username1/retrieve/subdir1/file3", fileInfos.get(3).getOsPath()); assertEquals("/home/username1/retrieve/subdir1/file4", fileInfos.get(4).getOsPath()); + assertEquals("async", fileInfos.get(4).getLocationType()); assertEquals("portal-file", fileInfos.get(5).getVirtualName()); + assertEquals("portal", fileInfos.get(5).getLocationType()); } @Test -- GitLab