Loading src/main/java/it/inaf/oats/vospace/UriService.java +31 −7 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.ProtocolNotSupportedException; Loading @@ -19,14 +20,13 @@ import it.inaf.oats.vospace.persistence.model.LocationType; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.ResultReference; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Param; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import org.springframework.beans.factory.annotation.Autowired; Loading Loading @@ -54,6 +54,9 @@ public class UriService { @Autowired private ServletRapClient rapClient; @Autowired private CreateNodeController createNodeController; public void setTransferJobResult(JobSummary job, Transfer transfer) { List<ResultReference> results = new ArrayList<>(); Loading Loading @@ -81,18 +84,39 @@ public class UriService { protocol.setEndpoint(getEndpoint(job, transfer)); } private Node getEndpointNode(String relativePath, JobService.JobType jobType, User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { return optNode.get(); } else { switch (jobType) { case pullFromVoSpace: throw new NodeNotFoundException(relativePath); case pushToVoSpace: case pullToVoSpace: DataNode newNode = new DataNode(); newNode.setUri(relativePath); return createNodeController.createNode(newNode, user); default: throw new InternalFaultException("No supported job direction specified"); } } } private String getEndpoint(JobSummary job, Transfer transfer) { String relativePath = transfer.getTarget().substring("vos://".length() + authority.length()); Node node = nodeDao.listNode(relativePath).orElseThrow(() -> new NodeNotFoundException(relativePath)); User user = (User) servletRequest.getUserPrincipal(); String creator = user.getName(); List<String> groups = user.getGroups(); // Check privileges write or read according to job type JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); Node node = this.getEndpointNode(relativePath, jobType, user); switch (jobType) { case pushToVoSpace: Loading @@ -109,7 +133,7 @@ public class UriService { break; default: throw new InternalFaultException("No job direction specified"); throw new InternalFaultException("No supported job direction specified"); } if (NodeUtils.getIsBusy(node)) { Loading src/main/java/it/inaf/oats/vospace/exception/ContainerNotFoundException.java +4 −2 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.NOT_FOUND) public class ContainerNotFoundException extends VoSpaceException { public class ContainerNotFoundException extends VoSpaceErrorSummarizableException { public ContainerNotFoundException(String path) { super("Container Not Found at path: " + path); super("Container Not Found at path: " + path, ErrorSummaryFactory.VOSpaceFault.NODE_NOT_FOUND); } } src/main/java/it/inaf/oats/vospace/exception/LinkFoundException.java +4 −2 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class LinkFoundException extends VoSpaceException { public class LinkFoundException extends VoSpaceErrorSummarizableException { public LinkFoundException(String path) { super("Link Found at path: " + path); super("Link Found at path: " + path, ErrorSummaryFactory.VOSpaceFault.INVALID_URI); } } src/test/java/it/inaf/oats/vospace/UriServiceTest.java +74 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import it.inaf.oats.vospace.persistence.model.LocationType; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; 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; Loading @@ -21,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; Loading @@ -46,6 +48,9 @@ public class UriServiceTest { @MockBean private ServletRapClient rapClient; @MockBean private CreateNodeController createNodeController; @Autowired private HttpServletRequest servletRequest; Loading Loading @@ -124,6 +129,59 @@ public class UriServiceTest { assertEquals("http://file-service/mydata1?jobId=job-id&token=<new-token>", job.getResults().get(0).getHref()); } @Test public void pushToNonexistentNode() { ContainerNode node = new ContainerNode(); node.setUri("vos://example.com!vospace/mydata1"); Property creator = new Property(); creator.setUri(NodeProperties.CREATOR_URI); creator.setValue("user1"); node.getProperties().add(creator); Property readgroup = new Property(); readgroup.setUri(NodeProperties.GROUP_READ_URI); readgroup.setValue("group1"); node.getProperties().add(readgroup); DataNode dnode = new DataNode(); dnode.setUri("vos://example.com!vospace/mydata1/mydata2"); dnode.getProperties().add(creator); dnode.getProperties().add(readgroup); Property writegroup = new Property(); writegroup.setUri(NodeProperties.GROUP_WRITE_URI); writegroup.setValue("group1"); dnode.getProperties().add(writegroup); when(nodeDAO.listNode(eq("/mydata1"))).thenReturn(Optional.of(node)); when(nodeDAO.listNode(eq("/mydata1/mydata2"))).thenReturn(Optional.empty()); User user = mock(User.class); when(user.getAccessToken()).thenReturn("<token>"); when(user.getName()).thenReturn("user1"); when(servletRequest.getUserPrincipal()).thenReturn(user); when(rapClient.exchangeToken(argThat(req -> { assertEquals("<token>", req.getSubjectToken()); assertEquals("http://file-service/mydata1/mydata2", req.getResource()); return true; }), any())).thenReturn("<new-token>"); JobSummary job = getPushToVoSpaceJob(); Transfer tr = uriService.getTransfer(job); when(createNodeController.createNode(any(), eq(user))).thenReturn(dnode); uriService.setTransferJobResult(job, tr); verify(createNodeController, times(1)).createNode(any(), eq(user)); assertEquals("http://file-service/mydata1/mydata2?jobId=job-id2&token=<new-token>", job.getResults().get(0).getHref()); } @Test public void setNodeRemoteLocationTest() { Loading Loading @@ -156,4 +214,20 @@ public class UriServiceTest { return job; } private JobSummary getPushToVoSpaceJob() { Transfer transfer = new Transfer(); transfer.setTarget("vos://example.com!vospace/mydata1/mydata2"); transfer.setDirection(JobService.JobType.pushToVoSpace.toString()); JobSummary job = new JobSummary(); job.setJobId("job-id2"); JobSummary.JobInfo jobInfo = new JobSummary.JobInfo(); jobInfo.getAny().add(transfer); job.setJobInfo(jobInfo); return job; } } Loading
src/main/java/it/inaf/oats/vospace/UriService.java +31 −7 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.ProtocolNotSupportedException; Loading @@ -19,14 +20,13 @@ import it.inaf.oats.vospace.persistence.model.LocationType; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.ResultReference; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Param; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import org.springframework.beans.factory.annotation.Autowired; Loading Loading @@ -54,6 +54,9 @@ public class UriService { @Autowired private ServletRapClient rapClient; @Autowired private CreateNodeController createNodeController; public void setTransferJobResult(JobSummary job, Transfer transfer) { List<ResultReference> results = new ArrayList<>(); Loading Loading @@ -81,18 +84,39 @@ public class UriService { protocol.setEndpoint(getEndpoint(job, transfer)); } private Node getEndpointNode(String relativePath, JobService.JobType jobType, User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { return optNode.get(); } else { switch (jobType) { case pullFromVoSpace: throw new NodeNotFoundException(relativePath); case pushToVoSpace: case pullToVoSpace: DataNode newNode = new DataNode(); newNode.setUri(relativePath); return createNodeController.createNode(newNode, user); default: throw new InternalFaultException("No supported job direction specified"); } } } private String getEndpoint(JobSummary job, Transfer transfer) { String relativePath = transfer.getTarget().substring("vos://".length() + authority.length()); Node node = nodeDao.listNode(relativePath).orElseThrow(() -> new NodeNotFoundException(relativePath)); User user = (User) servletRequest.getUserPrincipal(); String creator = user.getName(); List<String> groups = user.getGroups(); // Check privileges write or read according to job type JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); Node node = this.getEndpointNode(relativePath, jobType, user); switch (jobType) { case pushToVoSpace: Loading @@ -109,7 +133,7 @@ public class UriService { break; default: throw new InternalFaultException("No job direction specified"); throw new InternalFaultException("No supported job direction specified"); } if (NodeUtils.getIsBusy(node)) { Loading
src/main/java/it/inaf/oats/vospace/exception/ContainerNotFoundException.java +4 −2 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.NOT_FOUND) public class ContainerNotFoundException extends VoSpaceException { public class ContainerNotFoundException extends VoSpaceErrorSummarizableException { public ContainerNotFoundException(String path) { super("Container Not Found at path: " + path); super("Container Not Found at path: " + path, ErrorSummaryFactory.VOSpaceFault.NODE_NOT_FOUND); } }
src/main/java/it/inaf/oats/vospace/exception/LinkFoundException.java +4 −2 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class LinkFoundException extends VoSpaceException { public class LinkFoundException extends VoSpaceErrorSummarizableException { public LinkFoundException(String path) { super("Link Found at path: " + path); super("Link Found at path: " + path, ErrorSummaryFactory.VOSpaceFault.INVALID_URI); } }
src/test/java/it/inaf/oats/vospace/UriServiceTest.java +74 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import it.inaf.oats.vospace.persistence.model.LocationType; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; 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; Loading @@ -21,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; Loading @@ -46,6 +48,9 @@ public class UriServiceTest { @MockBean private ServletRapClient rapClient; @MockBean private CreateNodeController createNodeController; @Autowired private HttpServletRequest servletRequest; Loading Loading @@ -124,6 +129,59 @@ public class UriServiceTest { assertEquals("http://file-service/mydata1?jobId=job-id&token=<new-token>", job.getResults().get(0).getHref()); } @Test public void pushToNonexistentNode() { ContainerNode node = new ContainerNode(); node.setUri("vos://example.com!vospace/mydata1"); Property creator = new Property(); creator.setUri(NodeProperties.CREATOR_URI); creator.setValue("user1"); node.getProperties().add(creator); Property readgroup = new Property(); readgroup.setUri(NodeProperties.GROUP_READ_URI); readgroup.setValue("group1"); node.getProperties().add(readgroup); DataNode dnode = new DataNode(); dnode.setUri("vos://example.com!vospace/mydata1/mydata2"); dnode.getProperties().add(creator); dnode.getProperties().add(readgroup); Property writegroup = new Property(); writegroup.setUri(NodeProperties.GROUP_WRITE_URI); writegroup.setValue("group1"); dnode.getProperties().add(writegroup); when(nodeDAO.listNode(eq("/mydata1"))).thenReturn(Optional.of(node)); when(nodeDAO.listNode(eq("/mydata1/mydata2"))).thenReturn(Optional.empty()); User user = mock(User.class); when(user.getAccessToken()).thenReturn("<token>"); when(user.getName()).thenReturn("user1"); when(servletRequest.getUserPrincipal()).thenReturn(user); when(rapClient.exchangeToken(argThat(req -> { assertEquals("<token>", req.getSubjectToken()); assertEquals("http://file-service/mydata1/mydata2", req.getResource()); return true; }), any())).thenReturn("<new-token>"); JobSummary job = getPushToVoSpaceJob(); Transfer tr = uriService.getTransfer(job); when(createNodeController.createNode(any(), eq(user))).thenReturn(dnode); uriService.setTransferJobResult(job, tr); verify(createNodeController, times(1)).createNode(any(), eq(user)); assertEquals("http://file-service/mydata1/mydata2?jobId=job-id2&token=<new-token>", job.getResults().get(0).getHref()); } @Test public void setNodeRemoteLocationTest() { Loading Loading @@ -156,4 +214,20 @@ public class UriServiceTest { return job; } private JobSummary getPushToVoSpaceJob() { Transfer transfer = new Transfer(); transfer.setTarget("vos://example.com!vospace/mydata1/mydata2"); transfer.setDirection(JobService.JobType.pushToVoSpace.toString()); JobSummary job = new JobSummary(); job.setJobId("job-id2"); JobSummary.JobInfo jobInfo = new JobSummary.JobInfo(); jobInfo.getAny().add(transfer); job.setJobInfo(jobInfo); return job; } }