Loading src/main/java/it/inaf/oats/vospace/AbstractNodeService.java +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ public abstract class AbstractNodeService { @Value("${vospace-authority}") protected String authority; @Autowired protected HttpServletRequest servletRequest; protected void validatePath(String path) { if (path.equals("/")) { throw new IllegalArgumentException("Cannot move root node or to root node"); Loading src/main/java/it/inaf/oats/vospace/CopyService.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class CopyService extends AbstractNodeService { try { // check source branch for read and lock it nodeBranchService.checkBranchForReadAndLock(sourcePath, jobId); nodeBranchService.checkBranchForReadAndLock(sourcePath, jobId, user); // Check destination Optional<ShortNodeDescriptor> destShortNodeDescriptor Loading src/main/java/it/inaf/oats/vospace/NodeBranchService.java +2 −8 Original line number Diff line number Diff line Loading @@ -33,15 +33,9 @@ public class NodeBranchService { @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void checkBranchForReadAndLock(String sourcePath, String jobId) { // Extract User permissions from servlet request User user = (User) servletRequest.getUserPrincipal(); public void checkBranchForReadAndLock(String sourcePath, String jobId, User user) { try { // Get source node Loading src/test/java/it/inaf/oats/vospace/CopyServiceTest.java +179 −27 Original line number Diff line number Diff line Loading @@ -14,9 +14,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.Arrays; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.Transfer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; Loading @@ -29,16 +27,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.dao.DuplicateKeyException; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.ContextConfiguration; @SpringBootTest @AutoConfigureMockMvc @ContextConfiguration(classes = {DataSourceConfigSingleton.class, CopyServiceTest.TestConfig.class}) @ContextConfiguration(classes = DataSourceConfigSingleton.class) @TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"}) @TestMethodOrder(OrderAnnotation.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) Loading @@ -48,29 +44,185 @@ public class CopyServiceTest { private String authority; @Autowired private MoveService moveService; private CopyService copyService; @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; @Test @Order(1) public void copyRootTest() { @TestConfiguration public static class TestConfig { assertThrows(IllegalArgumentException.class, () -> { copyService.processCopyNodes(getTransfer("/", "/pippo"), "job_pippo", getAnonymousUser()); } ); /** * Necessary because MockBean doesn't work with HttpServletRequest. */ @Bean @Primary public HttpServletRequest servletRequest() { HttpServletRequest request = mock(HttpServletRequest.class); User user = new User().setUserId("anonymous"); when(request.getUserPrincipal()).thenReturn(user); return request; assertThrows(IllegalArgumentException.class, () -> { copyService.processCopyNodes(getTransfer("/pippo", "/"), "job_pippo", getAnonymousUser()); } ); } @Test @Order(2) public void testNonExistingSourceNode() { assertThrows(NodeNotFoundException.class, () -> { copyService.processCopyNodes(getTransfer("/pippo", "/test2"), "job_pippo", getAnonymousUser()); } ); } @Test @Order(3) public void testCopyDeniedOnBusySource() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(NodeBusyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/mbusy", "/test3/m1"), "job_pippo", user); } ); } @Test @Order(4) public void testPermissionDeniedOnSource() { User user = mock(User.class); when(user.getName()).thenReturn("user1"); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1", "/test4"), "job_pippo", user); } ); } @Test @Order(5) public void testDontMoveIfStickySource() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/mstick", "/test4"), "job_pippo", user); } ); } @Test @Order(6) public void testPermissionDeniedOnExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user1"); when(user.getGroups()).thenReturn(List.of("group1")); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/group1", "/test3/m1/m2"), "job_pippo", user); } ); } @Test @Order(7) public void testDestinationExistsAndIsBusy() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(NodeBusyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1", "/test3/mbusy"), "job_pippo", user); } ); } // Stub Test Class @Test @Order(9) public void testCopyToExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test4"); assertTrue(destId.isPresent()); // copy copyService.processCopyNodes(getTransfer("/test3/m1", "/test4"), "job_pippo", user); // source has been moved Optional<Long> oldSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(oldSourceId.isPresent()); Optional<Long> oldChildId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(oldChildId.isPresent()); Optional<Long> newSourceId = nodeDao.getNodeId("/test4/m1"); assertTrue(newSourceId.isPresent()); Optional<Long> newChildId = nodeDao.getNodeId("/test4/m1/m2"); assertTrue(newChildId.isPresent()); } @Test @Order(10) public void testCopyToExistingParent() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test3/m1/m2_copy"); assertTrue(destId.isEmpty()); // copy copyService.processCopyNodes(getTransfer("/test3/m1/m2", "/test3/m1/m2_copy"), "job_pippo", user); // source has been moved Optional<Long> oldSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(oldSourceId.isPresent()); Optional<Long> oldChildId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(oldChildId.isPresent()); Optional<Long> newSourceId = nodeDao.getNodeId("/test3/m1/m2_copy"); assertTrue(newSourceId.isPresent()); } @Test @Order(11) public void testCopyDeniedToExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); assertThrows(DuplicateKeyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1/m2", "/test3/m1"), "job_pippo", user); } ); } private Transfer getTransfer(String vosTarget, String vosDestination) { Transfer transfer = new Transfer(); transfer.setTarget(Arrays.asList("vos://" + this.authority + vosTarget)); transfer.setDirection("vos://" + this.authority + vosDestination); return transfer; } private User getAnonymousUser() { return new User().setUserId("anonymous"); } } src/test/java/it/inaf/oats/vospace/MoveServiceTest.java +0 −3 Original line number Diff line number Diff line Loading @@ -188,9 +188,6 @@ public class MoveServiceTest { Optional<Long> destParentId = nodeDao.getNodeId("/test4"); assertTrue(destParentId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test4"); assertTrue(destId.isPresent()); // move moveService.processMoveJob(getTransfer("/test3/m1", "/test4"), user); Loading Loading
src/main/java/it/inaf/oats/vospace/AbstractNodeService.java +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ public abstract class AbstractNodeService { @Value("${vospace-authority}") protected String authority; @Autowired protected HttpServletRequest servletRequest; protected void validatePath(String path) { if (path.equals("/")) { throw new IllegalArgumentException("Cannot move root node or to root node"); Loading
src/main/java/it/inaf/oats/vospace/CopyService.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class CopyService extends AbstractNodeService { try { // check source branch for read and lock it nodeBranchService.checkBranchForReadAndLock(sourcePath, jobId); nodeBranchService.checkBranchForReadAndLock(sourcePath, jobId, user); // Check destination Optional<ShortNodeDescriptor> destShortNodeDescriptor Loading
src/main/java/it/inaf/oats/vospace/NodeBranchService.java +2 −8 Original line number Diff line number Diff line Loading @@ -33,15 +33,9 @@ public class NodeBranchService { @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void checkBranchForReadAndLock(String sourcePath, String jobId) { // Extract User permissions from servlet request User user = (User) servletRequest.getUserPrincipal(); public void checkBranchForReadAndLock(String sourcePath, String jobId, User user) { try { // Get source node Loading
src/test/java/it/inaf/oats/vospace/CopyServiceTest.java +179 −27 Original line number Diff line number Diff line Loading @@ -14,9 +14,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.Arrays; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.Transfer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; Loading @@ -29,16 +27,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.dao.DuplicateKeyException; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.ContextConfiguration; @SpringBootTest @AutoConfigureMockMvc @ContextConfiguration(classes = {DataSourceConfigSingleton.class, CopyServiceTest.TestConfig.class}) @ContextConfiguration(classes = DataSourceConfigSingleton.class) @TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"}) @TestMethodOrder(OrderAnnotation.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) Loading @@ -48,29 +44,185 @@ public class CopyServiceTest { private String authority; @Autowired private MoveService moveService; private CopyService copyService; @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; @Test @Order(1) public void copyRootTest() { @TestConfiguration public static class TestConfig { assertThrows(IllegalArgumentException.class, () -> { copyService.processCopyNodes(getTransfer("/", "/pippo"), "job_pippo", getAnonymousUser()); } ); /** * Necessary because MockBean doesn't work with HttpServletRequest. */ @Bean @Primary public HttpServletRequest servletRequest() { HttpServletRequest request = mock(HttpServletRequest.class); User user = new User().setUserId("anonymous"); when(request.getUserPrincipal()).thenReturn(user); return request; assertThrows(IllegalArgumentException.class, () -> { copyService.processCopyNodes(getTransfer("/pippo", "/"), "job_pippo", getAnonymousUser()); } ); } @Test @Order(2) public void testNonExistingSourceNode() { assertThrows(NodeNotFoundException.class, () -> { copyService.processCopyNodes(getTransfer("/pippo", "/test2"), "job_pippo", getAnonymousUser()); } ); } @Test @Order(3) public void testCopyDeniedOnBusySource() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(NodeBusyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/mbusy", "/test3/m1"), "job_pippo", user); } ); } @Test @Order(4) public void testPermissionDeniedOnSource() { User user = mock(User.class); when(user.getName()).thenReturn("user1"); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1", "/test4"), "job_pippo", user); } ); } @Test @Order(5) public void testDontMoveIfStickySource() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/mstick", "/test4"), "job_pippo", user); } ); } @Test @Order(6) public void testPermissionDeniedOnExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user1"); when(user.getGroups()).thenReturn(List.of("group1")); assertThrows(PermissionDeniedException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/group1", "/test3/m1/m2"), "job_pippo", user); } ); } @Test @Order(7) public void testDestinationExistsAndIsBusy() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); assertThrows(NodeBusyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1", "/test3/mbusy"), "job_pippo", user); } ); } // Stub Test Class @Test @Order(9) public void testCopyToExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test4"); assertTrue(destId.isPresent()); // copy copyService.processCopyNodes(getTransfer("/test3/m1", "/test4"), "job_pippo", user); // source has been moved Optional<Long> oldSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(oldSourceId.isPresent()); Optional<Long> oldChildId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(oldChildId.isPresent()); Optional<Long> newSourceId = nodeDao.getNodeId("/test4/m1"); assertTrue(newSourceId.isPresent()); Optional<Long> newChildId = nodeDao.getNodeId("/test4/m1/m2"); assertTrue(newChildId.isPresent()); } @Test @Order(10) public void testCopyToExistingParent() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test3/m1/m2_copy"); assertTrue(destId.isEmpty()); // copy copyService.processCopyNodes(getTransfer("/test3/m1/m2", "/test3/m1/m2_copy"), "job_pippo", user); // source has been moved Optional<Long> oldSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(oldSourceId.isPresent()); Optional<Long> oldChildId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(oldChildId.isPresent()); Optional<Long> newSourceId = nodeDao.getNodeId("/test3/m1/m2_copy"); assertTrue(newSourceId.isPresent()); } @Test @Order(11) public void testCopyDeniedToExistingDestination() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); // Preliminary checks for assumptions Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); assertThrows(DuplicateKeyException.class, () -> { copyService.processCopyNodes(getTransfer("/test3/m1/m2", "/test3/m1"), "job_pippo", user); } ); } private Transfer getTransfer(String vosTarget, String vosDestination) { Transfer transfer = new Transfer(); transfer.setTarget(Arrays.asList("vos://" + this.authority + vosTarget)); transfer.setDirection("vos://" + this.authority + vosDestination); return transfer; } private User getAnonymousUser() { return new User().setUserId("anonymous"); } }
src/test/java/it/inaf/oats/vospace/MoveServiceTest.java +0 −3 Original line number Diff line number Diff line Loading @@ -188,9 +188,6 @@ public class MoveServiceTest { Optional<Long> destParentId = nodeDao.getNodeId("/test4"); assertTrue(destParentId.isPresent()); Optional<Long> destId = nodeDao.getNodeId("/test4"); assertTrue(destId.isPresent()); // move moveService.processMoveJob(getTransfer("/test3/m1", "/test4"), user); Loading