Commit a390773c authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

Edge case: links in container node + tests

parent 36c10c59
......@@ -7,14 +7,19 @@ package it.inaf.oats.vospace;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.datamodel.Views;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.vospace.v2.ContainerNode;
import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Transfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
......@@ -41,10 +46,13 @@ public class FileServiceClient {
@Autowired
private HttpServletRequest request;
@Autowired
private LinkService linkService;
@Autowired
private NodeDAO nodeDAO;
public String startArchiveJob(Transfer transfer, String jobId) {
String target = transfer.getTarget().substring("vos://".length() + authority.length());
......@@ -69,11 +77,33 @@ public class FileServiceClient {
// Add target path
vosPaths.add(target);
}
// OK generate descriptors
// Generate descriptors
// Expand container nodes into direct children list
List<String> expandedVosPaths = new ArrayList<>();
for (String vosPath : vosPaths) {
Node node
= nodeDAO.listNode(vosPath)
.orElseThrow(() -> {
throw new NodeNotFoundException(vosPath);
});
if (node instanceof ContainerNode) {
List<Node> nodes = ((ContainerNode) node).getNodes();
if (nodes.isEmpty()) {
expandedVosPaths.add(NodeUtils.getVosPath(node));
} else {
expandedVosPaths.addAll(nodes
.stream().map(n -> NodeUtils.getVosPath(n))
.collect(Collectors.toList()));
}
}
}
// follow links to links in vosPaths
List<ArchiveEntryDescriptor> entryDescriptors = linkService.followLinksForArchiveService(vosPaths);
List<ArchiveEntryDescriptor> entryDescriptors = linkService.followLinksForArchiveService(expandedVosPaths);
ArchiveRequest archiveRequest = new ArchiveRequest();
archiveRequest.setJobId(jobId);
......@@ -97,17 +127,17 @@ public class FileServiceClient {
return res.getHeaders().getLocation().toString();
}, new Object[]{});
}
public void startFileCopyJob(String sourceVosPath,
public void startFileCopyJob(String sourceVosPath,
String destiantionVosPath, String jobId, User user) {
CopyRequest copyRequest = new CopyRequest();
copyRequest.setJobId(jobId);
copyRequest.setSourceRootVosPath(sourceVosPath);
copyRequest.setDestinationRootVosPath(destiantionVosPath);
String url = fileServiceUrl + "/copy";
String token = user.getAccessToken();
restTemplate.execute(url, HttpMethod.POST, req -> {
HttpHeaders headers = req.getHeaders();
......@@ -119,12 +149,12 @@ public class FileServiceClient {
try (OutputStream os = req.getBody()) {
MAPPER.writeValue(os, copyRequest);
}
}, res -> {
return null;
}, res -> {
return null;
}, new Object[]{});
}
public static class CopyRequest {
private String jobId;
......@@ -161,7 +191,7 @@ public class FileServiceClient {
private String type;
private String jobId;
private List<ArchiveEntryDescriptor> entryDescriptors;
private List<ArchiveEntryDescriptor> entryDescriptors;
public String getType() {
return type;
......
......@@ -67,7 +67,7 @@ public class LinkService {
}
private ArchiveEntryDescriptor getLinkNodeArchiveEntryDescriptor(LinkNode node){
String vosPath = NodeUtils.getVosPath(node);
String vosPath = NodeUtils.getVosPath(node);
String targetNodeVosPath = NodeUtils.getVosPath(this.followLink(node));
return new ArchiveEntryDescriptor(vosPath, targetNodeVosPath);
......
......@@ -11,12 +11,16 @@ import it.inaf.oats.vospace.FileServiceClient.ArchiveRequest;
import it.inaf.oats.vospace.datamodel.Views;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.vospace.v2.ContainerNode;
import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.Param;
import net.ivoa.xml.vospace.v2.Transfer;
import net.ivoa.xml.vospace.v2.View;
......@@ -30,6 +34,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
......@@ -59,6 +64,9 @@ public class FileServiceClientTest {
@Mock
private LinkService linkService;
@Mock
private NodeDAO nodeDAO;
@InjectMocks
private FileServiceClient fileServiceClient;
......@@ -98,6 +106,11 @@ public class FileServiceClientTest {
view.setUri(Views.ZIP_VIEW_URI);
transfer.setView(view);
ContainerNode node = Mockito.mock(ContainerNode.class);
when(node.getNodes()).thenReturn(List.of());
when(node.getUri()).thenReturn("vos://example.com!vospace/mydir");
when(nodeDAO.listNode(eq("/mydir"))).thenReturn(Optional.of(node));
when(linkService.followLinksForArchiveService(any()))
.thenReturn(List.of(new ArchiveEntryDescriptor("/mydir")));
......@@ -162,6 +175,14 @@ public class FileServiceClientTest {
param2.setValue("file2");
view.getParam().add(param2);
DataNode node1 = Mockito.mock(DataNode.class);
when(node1.getUri()).thenReturn("vos://example.com!vospace/parent_dir/file1");
when(nodeDAO.listNode(eq("/parent_dir/file1"))).thenReturn(Optional.of(node1));
DataNode node2 = Mockito.mock(DataNode.class);
when(node2.getUri()).thenReturn("vos://example.com!vospace/parent_dir/file2");
when(nodeDAO.listNode(eq("/parent_dir/file2"))).thenReturn(Optional.of(node2));
when(linkService.followLinksForArchiveService(any())).thenReturn(
List.of(new ArchiveEntryDescriptor("/parent_dir/file1"),
new ArchiveEntryDescriptor("/parent_dir/file2")
......
/*
* This file is part of vospace-rest
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.oats.vospace;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton;
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
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;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
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.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.ContextConfiguration;
@SpringBootTest
//@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"})
@ContextConfiguration(classes = {DataSourceConfigSingleton.class})
public class LinkServiceTest {
@Autowired
private LinkService linkService;
@Test
public void testFollowLinksForArchiveService() {
List<String> vosPaths = List.of("/test3/m1/link2", "/test3/m1/m2");
List<ArchiveEntryDescriptor> aed = linkService.followLinksForArchiveService(vosPaths);
assertEquals(2, aed.size());
List<String> targetVosPaths = aed.stream().map(a -> a.getTargetNodeVosPath())
.collect(Collectors.toList());
System.out.println(targetVosPaths);
assertTrue(targetVosPaths.containsAll(List.of("/test3/m1/m2", "/test1/f1/f2_renamed/f3")));
}
}
......@@ -43,6 +43,7 @@ INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, gro
INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id) VALUES ('19', '', 'destination2', 'container', 'user3', '{"group1"}', '{"group1"}', false, 3); -- /mycontainer/destination2
INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id) VALUES ('19.21', '20', 'control', 'container', 'user3', '{"group1"}', '{"group1"}', false, 3); -- /mycontainer/destination2/control
INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id, target) VALUES ('9.10', '', 'link2', 'link', 'user3', '{"group1"}', '{"group1"}', false, 3, 'vos://example.com!vospace/test1/f1/f2_renamed/f3'); -- /test3/m1/link2
DELETE FROM job;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment