From e906ee239fb30791c76a6e3d9410e75f24962f01 Mon Sep 17 00:00:00 2001 From: Sonia Zorba <sonia.zorba@inaf.it> Date: Wed, 14 Jul 2021 14:57:50 +0200 Subject: [PATCH] Used view parameters instead of multiple targets for tar/zip archive generation --- .../inaf/oats/vospace/FileServiceClient.java | 34 +++++++-- .../oats/vospace/FileServiceClientTest.java | 69 ++++++++++++++++++- .../it/inaf/oats/vospace/UriServiceTest.java | 31 ++++++--- 3 files changed, 120 insertions(+), 14 deletions(-) diff --git a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java index 55fe579..d7f085a 100644 --- a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java +++ b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java @@ -7,6 +7,8 @@ package it.inaf.oats.vospace; import com.fasterxml.jackson.databind.ObjectMapper; import it.inaf.ia2.aa.data.User; +import it.inaf.oats.vospace.datamodel.Views; +import it.inaf.oats.vospace.exception.InvalidArgumentException; import java.io.OutputStream; import java.util.List; import java.util.stream.Collectors; @@ -39,8 +41,32 @@ public class FileServiceClient { public String startArchiveJob(Transfer transfer, String jobId) { - List<String> vosPaths = transfer.getTarget().stream() - .map(p -> p.substring("vos://".length() + authority.length())).collect(Collectors.toList()); + if (transfer.getTarget().size() != 1) { + throw new IllegalArgumentException("Target size is " + transfer.getTarget().size()); + } + + String target = transfer.getTarget().get(0); + + String viewUri = transfer.getView().getUri(); + + // Generate list of paths using view include parameters + List<String> vosPaths = transfer.getView().getParam().stream() + .map(p -> { + if (p.getUri().equals(viewUri + "/include")) { + if (p.getValue().contains("../")) { + throw new InvalidArgumentException("Relative paths are not supported"); + } + return target + "/" + p.getValue(); + } else { + throw new InvalidArgumentException("Unsupported view parameter: " + p.getUri()); + } + }) + .collect(Collectors.toList()); + + if (vosPaths.isEmpty()) { + // Add target path + vosPaths.add(target.substring("vos://".length() + authority.length())); + } ArchiveRequest archiveRequest = new ArchiveRequest(); archiveRequest.setJobId(jobId); @@ -98,9 +124,9 @@ public class FileServiceClient { private static String archiveTypeFromViewUri(String viewUri) { switch (viewUri) { - case "ivo://ia2.inaf.it/vospace/views#tar": + case Views.TAR_VIEW_URI: return "TAR"; - case "ivo://ia2.inaf.it/vospace/views#zip": + case Views.ZIP_VIEW_URI: return "ZIP"; default: throw new IllegalArgumentException("Archive type not defined for " + viewUri); diff --git a/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java b/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java index aded67f..ae6af0a 100644 --- a/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java +++ b/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java @@ -7,13 +7,16 @@ package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.Views; +import it.inaf.oats.vospace.exception.InvalidArgumentException; import java.io.ByteArrayOutputStream; import java.net.URI; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; +import net.ivoa.xml.vospace.v2.Param; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.View; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -75,15 +78,79 @@ public class FileServiceClientTest { } } + @Test + public void testArchiveNoInclude() { + + Transfer transfer = new Transfer(); + transfer.setDirection("pullFromVoSpace"); + transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydir")); + View view = new View(); + view.setUri(Views.ZIP_VIEW_URI); + transfer.setView(view); + + testStartArchiveJob(transfer); + } + + @Test + public void testInvalidViewParam() { + + Transfer transfer = new Transfer(); + transfer.setDirection("pullFromVoSpace"); + transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir")); + View view = new View(); + view.setUri(Views.TAR_VIEW_URI); + transfer.setView(view); + + Param param1 = new Param(); + param1.setUri("invalid"); + param1.setValue("file1"); + view.getParam().add(param1); + + assertThrows(InvalidArgumentException.class, () -> testStartArchiveJob(transfer)); + } + + @Test + public void testInvalidViewParamPath() { + + Transfer transfer = new Transfer(); + transfer.setDirection("pullFromVoSpace"); + transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir")); + View view = new View(); + view.setUri(Views.TAR_VIEW_URI); + transfer.setView(view); + + Param param1 = new Param(); + param1.setUri(Views.TAR_VIEW_URI + "/include"); + param1.setValue("../file1"); + view.getParam().add(param1); + + assertThrows(InvalidArgumentException.class, () -> testStartArchiveJob(transfer)); + } + private void testStartArchiveJob(String viewUri) { Transfer transfer = new Transfer(); transfer.setDirection("pullFromVoSpace"); - transfer.setTarget(Arrays.asList("vos://example.com!vospace/file1", "vos://example.com!vospace/file2")); + transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir")); View view = new View(); view.setUri(viewUri); transfer.setView(view); + Param param1 = new Param(); + param1.setUri(viewUri + "/include"); + param1.setValue("file1"); + view.getParam().add(param1); + + Param param2 = new Param(); + param2.setUri(viewUri + "/include"); + param2.setValue("file2"); + view.getParam().add(param2); + + testStartArchiveJob(transfer); + } + + private void testStartArchiveJob(Transfer transfer) { + User user = mock(User.class); when(user.getAccessToken()).thenReturn("<token>"); when(request.getUserPrincipal()).thenReturn(user); diff --git a/src/test/java/it/inaf/oats/vospace/UriServiceTest.java b/src/test/java/it/inaf/oats/vospace/UriServiceTest.java index 8806661..4a59ad7 100644 --- a/src/test/java/it/inaf/oats/vospace/UriServiceTest.java +++ b/src/test/java/it/inaf/oats/vospace/UriServiceTest.java @@ -24,6 +24,7 @@ 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.Param; import net.ivoa.xml.vospace.v2.Property; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; @@ -66,7 +67,7 @@ public class UriServiceTest { @MockBean private CreateNodeService createNodeService; - + @MockBean private FileServiceClient fileServiceClient; @@ -150,7 +151,7 @@ public class UriServiceTest { assertEquals("http://file-service/mydata1?jobId=job-id&token=<new-token>", negotiatedTransfer.getProtocols().get(0).getEndpoint()); } - + @Test public void testPrivateUrlPermissionDenied() { @@ -185,7 +186,7 @@ public class UriServiceTest { uriService.getNegotiatedTransfer(job, tr); }); } - + @Test public void testPrivateUrlNodeBusy() { @@ -199,8 +200,8 @@ public class UriServiceTest { readgroup.setUri(NodeProperties.GROUP_READ_URI); readgroup.setValue("group1"); node.getProperties().add(readgroup); - - node.setBusy(Boolean.TRUE); + + node.setBusy(Boolean.TRUE); when(nodeDAO.listNode(eq("/mydata1"))).thenReturn(Optional.of(node)); @@ -413,7 +414,7 @@ public class UriServiceTest { public void testZipArchiveViewEndpoint() { testArchiveViewEndpoint(Views.ZIP_VIEW_URI); } - + @Test public void testInvalidTransferNoProtocols() { @@ -439,12 +440,23 @@ public class UriServiceTest { Transfer transfer = new Transfer(); transfer.setDirection("pullFromVoSpace"); - transfer.setTarget(Arrays.asList("vos://example.com!vospace/file1", "vos://example.com!vospace/file2")); + transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir")); Protocol protocol = new Protocol(); protocol.setUri("ivo://ivoa.net/vospace/core#httpget"); transfer.getProtocols().add(protocol); View view = new View(); view.setUri(viewUri); + + Param param1 = new Param(); + param1.setUri(viewUri + "/include"); + param1.setValue("file1"); + view.getParam().add(param1); + + Param param2 = new Param(); + param2.setUri(viewUri + "/include"); + param2.setValue("file2"); + view.getParam().add(param2); + transfer.setView(view); JobSummary job = new JobSummary(); @@ -453,8 +465,9 @@ public class UriServiceTest { jobInfo.getAny().add(transfer); job.setJobInfo(jobInfo); - mockPublicNode("file1"); - mockPublicNode("file2"); + mockPublicNode("parent_dir"); + mockPublicNode("parent_dir/file1"); + mockPublicNode("parent_dir/file2"); uriService.getNegotiatedTransfer(job, transfer); -- GitLab