Loading src/main/java/it/inaf/oats/vospace/JobService.java +38 −5 Original line number Diff line number Diff line Loading @@ -24,15 +24,39 @@ public class JobService { @Autowired private UriService uriService; @Autowired private MoveService moveService; @Autowired private AsyncTransferService asyncTransfService; public enum JobType { public enum JobDirection { pullToVoSpace, pullFromVoSpace, pushToVoSpace, pushFromVoSpace, moveNode, copyNode copyNode; public static JobDirection getJobDirectionEnumFromTransfer(Transfer transfer) { String direction = transfer.getDirection(); switch (direction) { case "pullToVoSpace": case "pullFromVoSpace": case "pushToVoSpace": case "pushFromVoSpace": return JobDirection.valueOf(direction); default: if (transfer.isKeepBytes()) { return JobDirection.copyNode; } else { return JobDirection.moveNode; } } } } public void setJobPhase(JobSummary job, String phase) { Loading Loading @@ -67,7 +91,7 @@ public class JobService { jobDAO.updateJob(job); switch (getJobType(transfer)) { switch (getJobDirection(transfer)) { case pullToVoSpace: handlePullToVoSpace(job, transfer); break; Loading @@ -75,6 +99,10 @@ public class JobService { case pushToVoSpace: handleVoSpaceUrlsListResult(job, transfer); break; case moveNode: throw new UnsupportedOperationException("Not implemented yet"); // handleMoveNode(job, transfer); // break; default: throw new UnsupportedOperationException("Not implemented yet"); } Loading Loading @@ -114,8 +142,13 @@ public class JobService { uriService.setTransferJobResult(job, transfer); } private JobType getJobType(Transfer transfer) { return JobType.valueOf(transfer.getDirection()); private void handleMoveNode(JobSummary job, Transfer transfer) { moveService.processMoveJob(job, transfer); } private JobDirection getJobDirection(Transfer transfer) { return JobDirection.getJobDirectionEnumFromTransfer(transfer); } /** Loading src/main/java/it/inaf/oats/vospace/MoveService.java 0 → 100644 +98 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Transfer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MoveService { @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; public void processMoveJob(JobSummary job, Transfer transfer) { // Get Source Path String sourcePath = transfer.getTarget(); // Get Destination Path (it's in transfer direction) String destinationPath = transfer.getDirection(); // Extract User permissions from servlet request User user = (User) servletRequest.getUserPrincipal(); Long sourceId = nodeDao.getNodeId(sourcePath); List<Node> branchList = nodeDao.listNodesInBranch(sourceId, true); // Check feasibility of move on source branch if (!isWritePermissionsValid(branchList, user)) { throw new PermissionDeniedException(sourcePath); } if(sourcePath.equals(destinationPath)) return; if(!isMoveable(branchList)) { throw new NodeBusyException(sourcePath); } // Set branch at busy nodeDao.setBranchBusy(sourceId, true); // Compare source and destination paths and see if it's just a rename if(NodeUtils.getParentPath(sourcePath).equals(NodeUtils.getParentPath(destinationPath))) { nodeDao.renameNode(sourceId, NodeUtils.getLastPathElement(destinationPath)); } else { this.moveNode(sourceId, sourcePath, destinationPath, user); } nodeDao.setBranchBusy(sourceId, false); } // All nodes must be writable by the user to have a true private boolean isWritePermissionsValid(List<Node> list, User user) { String userName = user.getName(); List<String> userGroups = user.getGroups(); return list.stream().allMatch((n) -> { return NodeUtils.checkIfWritable(n, userName, userGroups); }); } // All nodes must comply to have a true private boolean isMoveable(List<Node> list) { return list.stream().allMatch((n) -> { boolean busy = NodeUtils.getIsBusy(n); boolean sticky = Boolean.valueOf( NodeProperties.getNodePropertyByURI(n, NodeProperties.STICKY_URN)); return (!busy && !sticky); }); } private void moveNode(Long sourceId, String sourcePath, String destPath, User user) { } } src/main/java/it/inaf/oats/vospace/TransferController.java +2 −2 Original line number Diff line number Diff line Loading @@ -169,7 +169,7 @@ public class TransferController { @RequestParam(value = "PHASE", required = false) Optional<List<ExecutionPhase>> phase, @RequestParam(value = "AFTER", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Optional<LocalDateTime> after, @RequestParam(value = "LAST", required = false) Optional<Integer> last, @RequestParam(value = "direction", required = false) Optional<List<JobService.JobType>> direction, @RequestParam(value = "direction", required = false) Optional<List<JobService.JobDirection>> direction, User principal) { if (last.isPresent()) { Loading @@ -187,7 +187,7 @@ public class TransferController { phaseList = List.of(); } List<JobService.JobType> directionList; List<JobService.JobDirection> directionList; if (direction.isPresent()) { directionList = direction.get(); } else { Loading src/main/java/it/inaf/oats/vospace/UriService.java +10 −5 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ package it.inaf.oats.vospace; import it.inaf.ia2.aa.ServletRapClient; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.rap.client.call.TokenExchangeRequest; import it.inaf.oats.vospace.JobService.JobType; import it.inaf.oats.vospace.JobService.JobDirection; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; Loading Loading @@ -82,16 +82,20 @@ public class UriService { throw new InvalidArgumentException("Transfer contains no protocols"); } JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); JobService.JobDirection jobDirection = JobDirection.getJobDirectionEnumFromTransfer(transfer); List<String> validProtocolUris = new ArrayList<>(); switch (jobType) { switch (jobDirection) { case pullFromVoSpace: validProtocolUris.add("ivo://ivoa.net/vospace/core#httpget"); break; case pushToVoSpace: validProtocolUris.add("ivo://ivoa.net/vospace/core#httpput"); break; default: throw new InternalFaultException("Unsupported job direction specified"); } List<Protocol> validProtocols Loading @@ -113,7 +117,7 @@ public class UriService { } private Node getEndpointNode(String relativePath, JobService.JobType jobType, JobService.JobDirection jobType, User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { Loading Loading @@ -142,7 +146,8 @@ public class UriService { List<String> groups = user.getGroups(); // Check privileges write or read according to job type JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); JobService.JobDirection jobType = JobDirection.getJobDirectionEnumFromTransfer(transfer); Node node = this.getEndpointNode(relativePath, jobType, user); switch (jobType) { Loading src/main/java/it/inaf/oats/vospace/persistence/JobDAO.java +3 −3 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ public class JobDAO { int i = 0; ps.setString(++i, jobSummary.getJobId()); ps.setString(++i, jobSummary.getOwnerId()); ps.setObject(++i, getJobType(jobSummary), Types.OTHER); ps.setObject(++i, getJobDirection(jobSummary), Types.VARCHAR); ps.setObject(++i, jobSummary.getPhase().value(), Types.OTHER); ps.setObject(++i, toJson(jobSummary.getJobInfo()), Types.OTHER); Loading @@ -74,7 +74,7 @@ public class JobDAO { }); } private String getJobType(JobSummary jobSummary) { private String getJobDirection(JobSummary jobSummary) { List<Object> payload = jobSummary.getJobInfo().getAny(); if (payload.isEmpty()) { Loading Loading @@ -138,7 +138,7 @@ public class JobDAO { public Jobs getJobs(String userId, List<ExecutionPhase> phaseList, List<JobService.JobType> directionList, List<JobService.JobDirection> directionList, Optional<LocalDateTime> after, Optional<Integer> last ) { Loading Loading
src/main/java/it/inaf/oats/vospace/JobService.java +38 −5 Original line number Diff line number Diff line Loading @@ -24,15 +24,39 @@ public class JobService { @Autowired private UriService uriService; @Autowired private MoveService moveService; @Autowired private AsyncTransferService asyncTransfService; public enum JobType { public enum JobDirection { pullToVoSpace, pullFromVoSpace, pushToVoSpace, pushFromVoSpace, moveNode, copyNode copyNode; public static JobDirection getJobDirectionEnumFromTransfer(Transfer transfer) { String direction = transfer.getDirection(); switch (direction) { case "pullToVoSpace": case "pullFromVoSpace": case "pushToVoSpace": case "pushFromVoSpace": return JobDirection.valueOf(direction); default: if (transfer.isKeepBytes()) { return JobDirection.copyNode; } else { return JobDirection.moveNode; } } } } public void setJobPhase(JobSummary job, String phase) { Loading Loading @@ -67,7 +91,7 @@ public class JobService { jobDAO.updateJob(job); switch (getJobType(transfer)) { switch (getJobDirection(transfer)) { case pullToVoSpace: handlePullToVoSpace(job, transfer); break; Loading @@ -75,6 +99,10 @@ public class JobService { case pushToVoSpace: handleVoSpaceUrlsListResult(job, transfer); break; case moveNode: throw new UnsupportedOperationException("Not implemented yet"); // handleMoveNode(job, transfer); // break; default: throw new UnsupportedOperationException("Not implemented yet"); } Loading Loading @@ -114,8 +142,13 @@ public class JobService { uriService.setTransferJobResult(job, transfer); } private JobType getJobType(Transfer transfer) { return JobType.valueOf(transfer.getDirection()); private void handleMoveNode(JobSummary job, Transfer transfer) { moveService.processMoveJob(job, transfer); } private JobDirection getJobDirection(Transfer transfer) { return JobDirection.getJobDirectionEnumFromTransfer(transfer); } /** Loading
src/main/java/it/inaf/oats/vospace/MoveService.java 0 → 100644 +98 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Transfer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MoveService { @Autowired private NodeDAO nodeDao; @Autowired private HttpServletRequest servletRequest; public void processMoveJob(JobSummary job, Transfer transfer) { // Get Source Path String sourcePath = transfer.getTarget(); // Get Destination Path (it's in transfer direction) String destinationPath = transfer.getDirection(); // Extract User permissions from servlet request User user = (User) servletRequest.getUserPrincipal(); Long sourceId = nodeDao.getNodeId(sourcePath); List<Node> branchList = nodeDao.listNodesInBranch(sourceId, true); // Check feasibility of move on source branch if (!isWritePermissionsValid(branchList, user)) { throw new PermissionDeniedException(sourcePath); } if(sourcePath.equals(destinationPath)) return; if(!isMoveable(branchList)) { throw new NodeBusyException(sourcePath); } // Set branch at busy nodeDao.setBranchBusy(sourceId, true); // Compare source and destination paths and see if it's just a rename if(NodeUtils.getParentPath(sourcePath).equals(NodeUtils.getParentPath(destinationPath))) { nodeDao.renameNode(sourceId, NodeUtils.getLastPathElement(destinationPath)); } else { this.moveNode(sourceId, sourcePath, destinationPath, user); } nodeDao.setBranchBusy(sourceId, false); } // All nodes must be writable by the user to have a true private boolean isWritePermissionsValid(List<Node> list, User user) { String userName = user.getName(); List<String> userGroups = user.getGroups(); return list.stream().allMatch((n) -> { return NodeUtils.checkIfWritable(n, userName, userGroups); }); } // All nodes must comply to have a true private boolean isMoveable(List<Node> list) { return list.stream().allMatch((n) -> { boolean busy = NodeUtils.getIsBusy(n); boolean sticky = Boolean.valueOf( NodeProperties.getNodePropertyByURI(n, NodeProperties.STICKY_URN)); return (!busy && !sticky); }); } private void moveNode(Long sourceId, String sourcePath, String destPath, User user) { } }
src/main/java/it/inaf/oats/vospace/TransferController.java +2 −2 Original line number Diff line number Diff line Loading @@ -169,7 +169,7 @@ public class TransferController { @RequestParam(value = "PHASE", required = false) Optional<List<ExecutionPhase>> phase, @RequestParam(value = "AFTER", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Optional<LocalDateTime> after, @RequestParam(value = "LAST", required = false) Optional<Integer> last, @RequestParam(value = "direction", required = false) Optional<List<JobService.JobType>> direction, @RequestParam(value = "direction", required = false) Optional<List<JobService.JobDirection>> direction, User principal) { if (last.isPresent()) { Loading @@ -187,7 +187,7 @@ public class TransferController { phaseList = List.of(); } List<JobService.JobType> directionList; List<JobService.JobDirection> directionList; if (direction.isPresent()) { directionList = direction.get(); } else { Loading
src/main/java/it/inaf/oats/vospace/UriService.java +10 −5 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ package it.inaf.oats.vospace; import it.inaf.ia2.aa.ServletRapClient; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.rap.client.call.TokenExchangeRequest; import it.inaf.oats.vospace.JobService.JobType; import it.inaf.oats.vospace.JobService.JobDirection; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; Loading Loading @@ -82,16 +82,20 @@ public class UriService { throw new InvalidArgumentException("Transfer contains no protocols"); } JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); JobService.JobDirection jobDirection = JobDirection.getJobDirectionEnumFromTransfer(transfer); List<String> validProtocolUris = new ArrayList<>(); switch (jobType) { switch (jobDirection) { case pullFromVoSpace: validProtocolUris.add("ivo://ivoa.net/vospace/core#httpget"); break; case pushToVoSpace: validProtocolUris.add("ivo://ivoa.net/vospace/core#httpput"); break; default: throw new InternalFaultException("Unsupported job direction specified"); } List<Protocol> validProtocols Loading @@ -113,7 +117,7 @@ public class UriService { } private Node getEndpointNode(String relativePath, JobService.JobType jobType, JobService.JobDirection jobType, User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { Loading Loading @@ -142,7 +146,8 @@ public class UriService { List<String> groups = user.getGroups(); // Check privileges write or read according to job type JobService.JobType jobType = JobType.valueOf(transfer.getDirection()); JobService.JobDirection jobType = JobDirection.getJobDirectionEnumFromTransfer(transfer); Node node = this.getEndpointNode(relativePath, jobType, user); switch (jobType) { Loading
src/main/java/it/inaf/oats/vospace/persistence/JobDAO.java +3 −3 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ public class JobDAO { int i = 0; ps.setString(++i, jobSummary.getJobId()); ps.setString(++i, jobSummary.getOwnerId()); ps.setObject(++i, getJobType(jobSummary), Types.OTHER); ps.setObject(++i, getJobDirection(jobSummary), Types.VARCHAR); ps.setObject(++i, jobSummary.getPhase().value(), Types.OTHER); ps.setObject(++i, toJson(jobSummary.getJobInfo()), Types.OTHER); Loading @@ -74,7 +74,7 @@ public class JobDAO { }); } private String getJobType(JobSummary jobSummary) { private String getJobDirection(JobSummary jobSummary) { List<Object> payload = jobSummary.getJobInfo().getAny(); if (payload.isEmpty()) { Loading Loading @@ -138,7 +138,7 @@ public class JobDAO { public Jobs getJobs(String userId, List<ExecutionPhase> phaseList, List<JobService.JobType> directionList, List<JobService.JobDirection> directionList, Optional<LocalDateTime> after, Optional<Integer> last ) { Loading