diff --git a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java index af5ecdbab62b8965f11651318af7345035c0a689..c1ab744098bba0530b78fda48a37a3769cbe9f66 100644 --- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java +++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java @@ -254,6 +254,7 @@ public class NodeDAO { } } + /* public Optional<String> getLtreePath(String nodeVosPath) { String sql = "SELECT path FROM node n " + "JOIN node_vos_path p ON n.node_id = p.node_id " @@ -277,16 +278,16 @@ public class NodeDAO { default: throw new InternalFaultException("More than 1 node at path: " + nodeVosPath); } - } + }*/ public Optional<ShortNodeDescriptor> getShortNodeDescriptor(String nodeVosPath, String userId, List<String> userGroups) { String sql = "SELECT path,\n" + "NOT (n.async_trans OR n.sticky OR loc.location_type = 'async' \n" - + "OR ( (SELECT COUNT(*) FROM (SELECT UNNEST(?) INTERSECT SELECT UNNEST(n.group_write))) = 0 AND\n" + + "OR ( (SELECT COUNT(*) FROM (SELECT UNNEST(?) INTERSECT SELECT UNNEST(n.group_write)) AS allowed_groups ) = 0 AND\n" + "n.creator_id <> ?)) AS is_writable,\n" - + "n.type = 'container' AS is_container\n" + + "n.type = 'container' AS is_container,\n" + "n.busy_state\n" + "FROM node n \n" + "JOIN node_vos_path p ON n.node_id = p.node_id \n" @@ -318,6 +319,7 @@ public class NodeDAO { } + /* public Optional<Node> getNodeById(Long nodeId, boolean enforceTapeStoredCheck) { String sql = "SELECT os.vos_path, loc.location_type, n.node_id, type, async_trans, sticky, busy_state, creator_id, group_read, group_write,\n" + "is_public, content_length, created_on, last_modified, accept_views, provide_views\n" @@ -351,7 +353,9 @@ public class NodeDAO { throw new InternalFaultException("Multiple nodes with id: " + nodeId); } } + */ + /* // First node is the root node public List<Node> listNodesInBranch(Long rootNodeId, boolean enforceTapeStoredCheck) { String sql = "SELECT os.vos_path, loc.location_type, n.node_id, type, async_trans, sticky, busy_state, creator_id, group_read, group_write,\n" @@ -378,8 +382,9 @@ public class NodeDAO { return result; - } + }*/ + /* public void setBranchBusy(Long rootNodeId, boolean busyState) { String sql = "UPDATE node SET busy_state = ?\n" + "WHERE path ~ ('*.' || ? || '.*')::lquery"; @@ -390,7 +395,7 @@ public class NodeDAO { ps.setLong(2, rootNodeId); return ps; }); - } + }*/ public void renameNode(Long nodeId, String name) { String sql = "UPDATE node SET name = ?\n" @@ -408,7 +413,7 @@ public class NodeDAO { public void moveNodeBranch(Long sourceRootId, String destParentLtreePath) { String sql = "UPDATE node c SET " - + "parent_path = (? || SUBLTREE(c.path, (SELECT nlevel(parent_path) FROM node WHERE node_id = ?), nlevel(c.path)))::ltree, " + + "parent_path = (? || SUBPATH(c.path, (SELECT nlevel(parent_path) FROM node WHERE node_id = ?), -1))::ltree, " + "parent_relative_path = COALESCE(c.parent_relative_path, c.parent_path) " // not sure about this + "FROM node n " + "WHERE n.path @> c.path AND n.node_id = ?"; diff --git a/src/test/java/it/inaf/oats/vospace/MoveServiceTest.java b/src/test/java/it/inaf/oats/vospace/MoveServiceTest.java index 0d1cb95f93476aa103907260e2b6feb752bef795..d30fece2a2e2d8b09c598e1cfdf56f8bef218ede 100644 --- a/src/test/java/it/inaf/oats/vospace/MoveServiceTest.java +++ b/src/test/java/it/inaf/oats/vospace/MoveServiceTest.java @@ -142,14 +142,14 @@ public class MoveServiceTest { when(user.getName()).thenReturn("user3"); when(servletRequest.getUserPrincipal()).thenReturn(user); - nodeDao.setBranchBusy(nodeDao.getNodeId("/test3/m1/m2").orElseThrow(), true); + //nodeDao.setBranchBusy(nodeDao.getNodeId("/test3/m1/m2").orElseThrow(), true); assertThrows(NodeBusyException.class, () -> { moveService.processMoveJob(getTransfer("/test3/m1", "/test4")); } ); - nodeDao.setBranchBusy(nodeDao.getNodeId("/test3/m1/m2").orElseThrow(), false); + //nodeDao.setBranchBusy(nodeDao.getNodeId("/test3/m1/m2").orElseThrow(), false); } @Test diff --git a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java index 3a6e266606b8dbcea432fe15ca42c0d10f2b0db7..2cc434da82489bd4ca187880d8a34ccb47358a9b 100644 --- a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java +++ b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java @@ -5,22 +5,24 @@ */ package it.inaf.oats.vospace.persistence; +import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeProperties; -import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.InternalFaultException; -import java.util.ArrayList; -import java.util.Arrays; +import it.inaf.oats.vospace.persistence.NodeDAO.ShortNodeDescriptor; import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Set; import javax.sql.DataSource; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.DataNode; -import net.ivoa.xml.vospace.v2.Node; -import net.ivoa.xml.vospace.v2.Property; import net.ivoa.xml.vospace.v2.View; import static org.junit.jupiter.api.Assertions.assertEquals; +import net.ivoa.xml.vospace.v2.Node; +import net.ivoa.xml.vospace.v2.Property; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; @@ -91,6 +93,7 @@ public class NodeDAOTest { assertTrue(id3.isEmpty()); } + /* @Test public void testGetNodeById() { Optional<Long> id1 = dao.getNodeId("/test1/f1"); @@ -105,8 +108,9 @@ public class NodeDAOTest { assertTrue(opt1.isPresent()); assertTrue(NodeUtils.getVosPath(opt1.get()).equals("/test1/f1")); - } + }*/ + /* @Test public void testListNodesInBranch() { Optional<Long> id1 = dao.getNodeId("/test1/f1"); @@ -123,8 +127,9 @@ public class NodeDAOTest { dao.listNodesInBranch(id1.get(), true); }); - } + }*/ + /* @Test public void testSetBranchBusy() { Optional<Long> rootId = dao.getNodeId("/test1/f1"); @@ -157,7 +162,135 @@ public class NodeDAOTest { ); assertTrue(busyFalse); + } */ + + @Test + public void testGetShortNodeDescriptor(){ + String userName = "user3"; + List<String> userGroups = List.of(); + + Optional<ShortNodeDescriptor> snd1Opt = + dao.getShortNodeDescriptor("/test3/mstick", userName, userGroups); + + assertTrue(snd1Opt.isPresent()); + ShortNodeDescriptor snd1 = snd1Opt.get(); + assertTrue(snd1.isContainer()); + assertFalse(snd1.isWritable()); + assertFalse(snd1.isBusy()); + + assertEquals("9.13", snd1.getDestinationNodeLtreePath()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/mbusy", userName, userGroups); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertTrue(snd1.isWritable()); + assertTrue(snd1.isBusy()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/masynctrans", userName, userGroups); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertFalse(snd1.isWritable()); + assertFalse(snd1.isBusy()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/asyncloc", userName, userGroups); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertFalse(snd1.isWritable()); + assertFalse(snd1.isBusy()); + + snd1Opt = + dao.getShortNodeDescriptor("/test1/f1/f2_renamed/f3", "user1", userGroups); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertFalse(snd1.isContainer()); + assertFalse(snd1.isWritable()); + assertFalse(snd1.isBusy()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/group1", "user1", userGroups); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertFalse(snd1.isWritable()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/group1", "user3", List.of("group99")); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertTrue(snd1.isWritable()); + + snd1Opt = + dao.getShortNodeDescriptor("/test3/group1", "user1", List.of("group1", "group2")); + assertTrue(snd1Opt.isPresent()); + snd1 = snd1Opt.get(); + assertTrue(snd1.isWritable()); + } + + @Test + public void testIsBranchBusy() { + Optional<Long> optId = dao.getNodeId("/test3/m1"); + assertTrue(optId.isPresent()); + + assertFalse(dao.isBranchBusy(optId.get())); + + optId = dao.getNodeId("/test3"); + assertTrue(optId.isPresent()); + + assertTrue(dao.isBranchBusy(optId.get())); + } + + @Test + public void testIsBranchWritable() { + + List<String> userGroups = List.of("group1"); + Optional<Long> optId = dao.getNodeId("/test3/m1"); + assertTrue(optId.isPresent()); + assertTrue(dao.isBranchWritable(optId.get(), "user3", userGroups)); + + optId = dao.getNodeId("/test3"); + assertTrue(optId.isPresent()); + assertFalse(dao.isBranchWritable(optId.get(), "user3", userGroups)); + + optId = dao.getNodeId("/test3/group1"); + assertTrue(optId.isPresent()); + assertTrue(dao.isBranchWritable(optId.get(), "user3", userGroups)); + + optId = dao.getNodeId("/test3/group1"); + assertTrue(optId.isPresent()); + assertFalse(dao.isBranchWritable(optId.get(), "user1", List.of("group99"))); + } + + @Test + public void testMoveNodeBranch() { + // Let's move /test3/m1 to /test3/group1 + Optional<Long> optSourceId = dao.getNodeId("/test3/m1"); + assertTrue(optSourceId.isPresent()); + + Optional<ShortNodeDescriptor> optSnd + = dao.getShortNodeDescriptor("/test3/group1", "user3", List.of("group1")); + + assertTrue(optSnd.isPresent()); + ShortNodeDescriptor snd = optSnd.get(); + + assertEquals("9.17", snd.getDestinationNodeLtreePath()); + dao.moveNodeBranch(optSourceId.get(), snd.getDestinationNodeLtreePath()); + + Optional<Long> optResultId = dao.getNodeId("/test3/group1/m1"); + assertTrue(optSourceId.isPresent()); + optSnd = dao.getShortNodeDescriptor("/test3/group1/m1", "user3", List.of("group1")); + assertEquals("9.17.10", optSnd.get().getDestinationNodeLtreePath()); + + + Optional<Long> optResultIdChild = dao.getNodeId("/test3/group1/m1/m2"); + optSnd = dao.getShortNodeDescriptor("/test3/group1/m1/m2", "user3", List.of("group1")); + assertEquals("9.17.10.11", optSnd.get().getDestinationNodeLtreePath()); + assertTrue(optResultIdChild.isPresent()); + + } + @Test public void testRenameNode() { @@ -181,40 +314,7 @@ public class NodeDAOTest { assertTrue(dao.listNode(newPathChild).isPresent()); } - - @Test - public void testMoveNodeBranch() { - Optional<Long> optSourceId = dao.getNodeId("/test1/f1"); - assertTrue(optSourceId.isPresent()); - - Optional<Long> optSourceId1 = dao.getNodeId("/test1/f1/f2_renamed"); - assertTrue(optSourceId1.isPresent()); - - Optional<Long> optSourceId2 = dao.getNodeId("/test1/f1/f2_renamed/f3"); - assertTrue(optSourceId2.isPresent()); - - Optional<Long> optDestId = dao.getNodeId("/test2/f4"); - assertTrue(optDestId.isPresent()); - - // dao.moveNodeBranch(optSourceId.get(), optDestId.get()); - - Optional<Long> newOptSourceId = dao.getNodeId("/test1/f1"); - assertTrue(newOptSourceId.isEmpty()); - - Optional<Long> dest = dao.getNodeId("/test2/f4/f1"); - assertTrue(dest.isPresent()); - assertEquals(dest.get(), optSourceId.get()); - - Optional<Long> dest1 = dao.getNodeId("/test2/f4/f1/f2_renamed"); - assertTrue(dest1.isPresent()); - assertEquals(dest1.get(), optSourceId1.get()); - - Optional<Long> dest2 = dao.getNodeId("/test2/f4/f1/f2_renamed/f3"); - assertTrue(dest2.isPresent()); - assertEquals(dest2.get(), optSourceId2.get()); - - } - + @Test public void testCountNodeWithPath() { assertEquals(1, dao.countNodesWithPath("/")); diff --git a/src/test/resources/test-data.sql b/src/test/resources/test-data.sql index adf89ffc32789671643f0ee3dff4190533043f90..ec04c997a261a61d4d9f7eabfbc764dd2be722bb 100644 --- a/src/test/resources/test-data.sql +++ b/src/test/resources/test-data.sql @@ -30,6 +30,11 @@ INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, is_ INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, is_public, location_id) VALUES ('', NULL, 'test4', 'container', 'user3', false, 3); -- /test4 INSERT INTO node (parent_path, parent_relative_path, name, sticky, type, creator_id, is_public, location_id) VALUES ('9', '', 'mstick', true, 'container', 'user3', false, 3); -- /test3/mstick +INSERT INTO node (parent_path, parent_relative_path, name, busy_state, type, creator_id, is_public, location_id) VALUES ('9', '', 'mbusy', true, 'container', 'user3', false, 3); -- /test3/mbusy +INSERT INTO node (parent_path, parent_relative_path, name, async_trans, type, creator_id, is_public, location_id) VALUES ('9', '', 'masynctrans', true, 'container', 'user3', false, 3); -- /test3/masynctrans +INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, is_public, location_id) VALUES ('9', '', 'asyncloc', 'container', 'user3', false, 1); -- /test3/asyncloc +INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, is_public, location_id) VALUES ('9', '', 'group1', 'container', 'user3','{"group1"}', false, 3); -- /test3/group1 + DELETE FROM job;