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

Added LinkNode support to pullFromVoSpace

parent be9d595e
...@@ -6,15 +6,21 @@ ...@@ -6,15 +6,21 @@
package it.inaf.oats.vospace; package it.inaf.oats.vospace;
import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.InvalidURIException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.vospace.v2.LinkNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
public abstract class BaseNodeController { public abstract class BaseNodeController {
@Autowired @Autowired
private HttpServletRequest servletRequest; private HttpServletRequest servletRequest;
@Value("${vospace-authority}")
protected String authority;
protected String getPath() { protected String getPath() {
String requestURL = servletRequest.getRequestURL().toString(); String requestURL = servletRequest.getRequestURL().toString();
try { try {
...@@ -27,4 +33,14 @@ public abstract class BaseNodeController { ...@@ -27,4 +33,14 @@ public abstract class BaseNodeController {
protected String getParentPath(String path) { protected String getParentPath(String path) {
return NodeUtils.getParentPath(path); return NodeUtils.getParentPath(path);
} }
protected void validateInternalLinkNode(LinkNode linkNode) {
String target = linkNode.getTarget();
// I validate it here to add context easily
if (target == null) {
throw new InvalidArgumentException("LinkNode in payload has no target element specified");
}
URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority);
}
} }
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package it.inaf.oats.vospace; package it.inaf.oats.vospace;
import it.inaf.ia2.aa.data.User; import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.InvalidURIException;
import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.LinkNode;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
...@@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
@RestController @RestController
public class CreateNodeController extends BaseNodeController { public class CreateNodeController extends BaseNodeController {
...@@ -27,9 +25,6 @@ public class CreateNodeController extends BaseNodeController { ...@@ -27,9 +25,6 @@ public class CreateNodeController extends BaseNodeController {
@Autowired @Autowired
private CreateNodeService createNodeService; private CreateNodeService createNodeService;
@Value("${vospace-authority}")
private String authority;
@PutMapping(value = {"/nodes", "/nodes/**"}, @PutMapping(value = {"/nodes", "/nodes/**"},
consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
...@@ -40,7 +35,7 @@ public class CreateNodeController extends BaseNodeController { ...@@ -40,7 +35,7 @@ public class CreateNodeController extends BaseNodeController {
LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path); LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path);
// Get Node path (and validates it too) // Get Node path (and validates it too)
String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), authority); String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), this.authority);
LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode); LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode);
...@@ -59,14 +54,7 @@ public class CreateNodeController extends BaseNodeController { ...@@ -59,14 +54,7 @@ public class CreateNodeController extends BaseNodeController {
private void validateInputNode(Node node) { private void validateInputNode(Node node) {
if (node instanceof LinkNode) { if (node instanceof LinkNode) {
LinkNode linkNode = (LinkNode) node; this.validateInternalLinkNode((LinkNode) node);
String target = linkNode.getTarget();
// I validate it here to add context easily
if (target == null) {
throw new InvalidArgumentException("LinkNode in payload has no target element specified");
}
URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority);
} }
} }
......
...@@ -13,6 +13,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO; ...@@ -13,6 +13,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.LinkNode;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.View; import net.ivoa.xml.vospace.v2.View;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -65,8 +66,11 @@ public class SetNodeController extends BaseNodeController { ...@@ -65,8 +66,11 @@ public class SetNodeController extends BaseNodeController {
// This method cannot be used to modify the accepts or provides list of Views for the Node. // This method cannot be used to modify the accepts or provides list of Views for the Node.
// Only DataNodes has Views (see VOSpace Data Model) // Only DataNodes has Views (see VOSpace Data Model)
// Also if input node is LinkNode, target must be validated as internal URI
if (node instanceof DataNode) { if (node instanceof DataNode) {
checkViews((DataNode) node, (DataNode) toBeModifiedNode); checkViews((DataNode) node, (DataNode) toBeModifiedNode);
} else if(node instanceof LinkNode) {
this.validateInternalLinkNode((LinkNode) node);
} }
//The service SHOULD throw a HTTP 500 status code including an InternalFault fault //The service SHOULD throw a HTTP 500 status code including an InternalFault fault
......
...@@ -32,6 +32,7 @@ import java.util.stream.Collectors; ...@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.JobSummary;
import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.LinkNode;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Protocol;
import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Transfer;
...@@ -77,7 +78,7 @@ public class UriService { ...@@ -77,7 +78,7 @@ public class UriService {
negotiatedTransfer.setTarget(transfer.getTarget()); negotiatedTransfer.setTarget(transfer.getTarget());
negotiatedTransfer.setDirection(transfer.getDirection()); negotiatedTransfer.setDirection(transfer.getDirection());
// according to examples found in specification view is not copied // according to examples found in specification view is not copied
if (transfer.getProtocols().isEmpty()) { if (transfer.getProtocols().isEmpty()) {
// At least one protocol is expected from client // At least one protocol is expected from client
throw new InvalidArgumentException("Transfer contains no protocols"); throw new InvalidArgumentException("Transfer contains no protocols");
...@@ -118,7 +119,7 @@ public class UriService { ...@@ -118,7 +119,7 @@ public class UriService {
} }
negotiatedTransfer.getProtocols().addAll(validProtocols); negotiatedTransfer.getProtocols().addAll(validProtocols);
return negotiatedTransfer; return negotiatedTransfer;
} }
...@@ -127,7 +128,16 @@ public class UriService { ...@@ -127,7 +128,16 @@ public class UriService {
User user) { User user) {
Optional<Node> optNode = nodeDao.listNode(relativePath); Optional<Node> optNode = nodeDao.listNode(relativePath);
if (optNode.isPresent()) { if (optNode.isPresent()) {
return optNode.get(); Node node = optNode.get();
if (jobType.equals(JobService.JobDirection.pullFromVoSpace)) {
if (node instanceof LinkNode) {
if (!NodeUtils.checkIfReadable(node, user.getName(), user.getGroups())) {
throw PermissionDeniedException.forPath(relativePath);
}
node = this.followLink((LinkNode) node);
}
}
return node;
} else { } else {
switch (jobType) { switch (jobType) {
case pullFromVoSpace: case pullFromVoSpace:
...@@ -152,8 +162,8 @@ public class UriService { ...@@ -152,8 +162,8 @@ public class UriService {
List<String> groups = user.getGroups(); List<String> groups = user.getGroups();
// Check privileges write or read according to job type // Check privileges write or read according to job type
JobService.JobDirection jobType = JobService.JobDirection jobType
JobDirection.getJobDirectionEnumFromTransfer(transfer); = JobDirection.getJobDirectionEnumFromTransfer(transfer);
Node node = this.getEndpointNode(relativePath, jobType, user); Node node = this.getEndpointNode(relativePath, jobType, user);
switch (jobType) { switch (jobType) {
...@@ -266,4 +276,11 @@ public class UriService { ...@@ -266,4 +276,11 @@ public class UriService {
return (Transfer) job.getJobInfo().getAny().get(0); return (Transfer) job.getJobInfo().getAny().get(0);
} }
private Node followLink(LinkNode linkNode) {
String targetPath = URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority);
Optional<Node> targetNode = nodeDao.listNode(targetPath);
return targetNode.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath));
}
} }
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