Loading src/main/java/it/inaf/oats/vospace/JobService.java +52 −23 Original line number Diff line number Diff line Loading @@ -6,8 +6,10 @@ import net.ivoa.xml.uws.v1.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import it.inaf.oats.vospace.exception.VoSpaceErrorSummarizableException; @Service public class JobService { Loading Loading @@ -61,30 +63,45 @@ public class JobService { } private void handlePullToVoSpace(JobSummary job, Transfer transfer) { try { for (Protocol protocol : transfer.getProtocols()) { switch (protocol.getUri()) { case "ia2:async-recall": asyncTransfService.startJob(job); // ASK IF IT's OK neglect phase update. return; case "ivo://ivoa.net/vospace/core#httpget": String nodeUri = transfer.getTarget(); String contentUri = protocol.getEndpoint(); uriService.setNodeRemoteLocation(nodeUri, contentUri); uriService.setTransferJobResult(job, transfer); job.setPhase(ExecutionPhase.COMPLETED); jobDAO.updateJob(job); return; default: throw new InternalFaultException("Unsupported pullToVoSpace protocol: " + protocol.getUri()); } } } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); jobDAO.updateJob(job); } } private void handleVoSpaceUrlsListResult(JobSummary job, Transfer transfer) { try { job.setPhase(ExecutionPhase.EXECUTING); uriService.setTransferJobResult(job, transfer); job.setPhase(ExecutionPhase.COMPLETED); // Need to catch other exceptions too to avoid inconsistent job status } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); } finally { jobDAO.updateJob(job); } } private JobType getJobType(Transfer transfer) { return JobType.valueOf(transfer.getDirection()); Loading @@ -92,11 +109,23 @@ public class JobService { /** * Synchronous transfer endpoint creates a job that is immediately set to * completed. * COMPLETED or to ERROR in case some fault occurred. * * In case of ERROR, Protocols are stripped from job representation in * compliance with specifications * */ public void createSyncJobResult(JobSummary job) { job.setPhase(ExecutionPhase.COMPLETED); try { uriService.setSyncTransferEndpoints(job); job.setPhase(ExecutionPhase.COMPLETED); // Need to catch other exceptions too to avoid inconsistent job status } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); uriService.getTransfer(job).getProtocols().clear(); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); } finally { jobDAO.createJob(job); } } } src/main/java/it/inaf/oats/vospace/TransferController.java +10 −7 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.persistence.JobDAO; import java.util.Optional; import java.util.UUID; Loading @@ -9,6 +10,7 @@ import net.ivoa.xml.uws.v1.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.Jobs; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Param; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; Loading @@ -23,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @RestController public class TransferController { Loading Loading @@ -115,11 +118,11 @@ public class TransferController { @RequestParam(value = "direction", required = false) Optional<List<JobService.JobType>> direction, User principal) { if(last.isPresent()) { if(last.get() <= 0) if (last.isPresent()) { if (last.get() <= 0) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); } } String userId = principal.getName(); Loading src/main/java/it/inaf/oats/vospace/UriService.java +43 −6 Original line number Diff line number Diff line Loading @@ -3,11 +3,15 @@ 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.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.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.ProtocolNotSupportedException; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.persistence.LocationDAO; import it.inaf.oats.vospace.persistence.NodeDAO; import it.inaf.oats.vospace.persistence.model.Location; Loading @@ -15,12 +19,14 @@ 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.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.ResultReference; 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 @@ -57,7 +63,8 @@ public class UriService { results.add(result); job.setResults(results); job.setPhase(ExecutionPhase.COMPLETED); // Moved phase setting to caller method for ERROR management // job.setPhase(ExecutionPhase.COMPLETED); } public void setSyncTransferEndpoints(JobSummary job) { Loading @@ -68,7 +75,8 @@ public class UriService { if (!"ivo://ivoa.net/vospace/core#httpget".equals(protocol.getUri()) && !"ivo://ivoa.net/vospace/core#httpput".equals(protocol.getUri())) { throw new IllegalStateException("Unsupported protocol " + protocol.getUri()); // throw new IllegalStateException("Unsupported protocol " + protocol.getUri()); throw new ProtocolNotSupportedException(protocol.getUri()); } protocol.setEndpoint(getEndpoint(job, transfer)); } Loading @@ -79,6 +87,35 @@ public class UriService { 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()); switch (jobType) { case pushToVoSpace: case pullToVoSpace: if (!NodeUtils.checkIfWritable(node, creator, groups)) { throw new PermissionDeniedException(relativePath); } break; case pullFromVoSpace: if (!NodeUtils.checkIfReadable(node, creator, groups)) { throw new PermissionDeniedException(relativePath); } break; default: throw new InternalFaultException("No job direction specified"); } if (NodeUtils.getIsBusy(node)) { throw new NodeBusyException(relativePath); } Location location = locationDAO.getNodeLocation(relativePath).orElse(null); String endpoint; Loading src/main/java/it/inaf/oats/vospace/exception/DuplicateNodeException.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.CONFLICT) public class DuplicateNodeException extends VoSpaceException { public class DuplicateNodeException extends VoSpaceErrorSummarizableException { public DuplicateNodeException(String path) { super("Duplicate Node at path: " + path); super("Duplicate Node at path: " + path, ErrorSummaryFactory.VOSpaceFault.DUPLICATE_NODE); } } src/main/java/it/inaf/oats/vospace/exception/InternalFaultException.java +6 −3 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) // Status code 500 public class InternalFaultException extends VoSpaceException { public class InternalFaultException extends VoSpaceErrorSummarizableException { private static final Logger LOG = LoggerFactory.getLogger(InternalFaultException.class); public InternalFaultException(String msg) { super("InternalFaultException: " + msg); super("InternalFaultException: " + msg, ErrorSummaryFactory.VOSpaceFault.INTERNAL_FAULT); } public InternalFaultException(Throwable cause) { super("InternalFaultException: " + getMessage(cause)); super("InternalFaultException: " + getMessage(cause), ErrorSummaryFactory.VOSpaceFault.INTERNAL_FAULT); } private static String getMessage(Throwable cause) { Loading Loading
src/main/java/it/inaf/oats/vospace/JobService.java +52 −23 Original line number Diff line number Diff line Loading @@ -6,8 +6,10 @@ import net.ivoa.xml.uws.v1.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import it.inaf.oats.vospace.exception.VoSpaceErrorSummarizableException; @Service public class JobService { Loading Loading @@ -61,30 +63,45 @@ public class JobService { } private void handlePullToVoSpace(JobSummary job, Transfer transfer) { try { for (Protocol protocol : transfer.getProtocols()) { switch (protocol.getUri()) { case "ia2:async-recall": asyncTransfService.startJob(job); // ASK IF IT's OK neglect phase update. return; case "ivo://ivoa.net/vospace/core#httpget": String nodeUri = transfer.getTarget(); String contentUri = protocol.getEndpoint(); uriService.setNodeRemoteLocation(nodeUri, contentUri); uriService.setTransferJobResult(job, transfer); job.setPhase(ExecutionPhase.COMPLETED); jobDAO.updateJob(job); return; default: throw new InternalFaultException("Unsupported pullToVoSpace protocol: " + protocol.getUri()); } } } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); jobDAO.updateJob(job); } } private void handleVoSpaceUrlsListResult(JobSummary job, Transfer transfer) { try { job.setPhase(ExecutionPhase.EXECUTING); uriService.setTransferJobResult(job, transfer); job.setPhase(ExecutionPhase.COMPLETED); // Need to catch other exceptions too to avoid inconsistent job status } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); } finally { jobDAO.updateJob(job); } } private JobType getJobType(Transfer transfer) { return JobType.valueOf(transfer.getDirection()); Loading @@ -92,11 +109,23 @@ public class JobService { /** * Synchronous transfer endpoint creates a job that is immediately set to * completed. * COMPLETED or to ERROR in case some fault occurred. * * In case of ERROR, Protocols are stripped from job representation in * compliance with specifications * */ public void createSyncJobResult(JobSummary job) { job.setPhase(ExecutionPhase.COMPLETED); try { uriService.setSyncTransferEndpoints(job); job.setPhase(ExecutionPhase.COMPLETED); // Need to catch other exceptions too to avoid inconsistent job status } catch (VoSpaceErrorSummarizableException e) { job.setPhase(ExecutionPhase.ERROR); uriService.getTransfer(job).getProtocols().clear(); job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e.getFault())); } finally { jobDAO.createJob(job); } } }
src/main/java/it/inaf/oats/vospace/TransferController.java +10 −7 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.persistence.JobDAO; import java.util.Optional; import java.util.UUID; Loading @@ -9,6 +10,7 @@ import net.ivoa.xml.uws.v1.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.Jobs; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Param; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; Loading @@ -23,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @RestController public class TransferController { Loading Loading @@ -115,11 +118,11 @@ public class TransferController { @RequestParam(value = "direction", required = false) Optional<List<JobService.JobType>> direction, User principal) { if(last.isPresent()) { if(last.get() <= 0) if (last.isPresent()) { if (last.get() <= 0) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); } } String userId = principal.getName(); Loading
src/main/java/it/inaf/oats/vospace/UriService.java +43 −6 Original line number Diff line number Diff line Loading @@ -3,11 +3,15 @@ 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.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.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.ProtocolNotSupportedException; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.persistence.LocationDAO; import it.inaf.oats.vospace.persistence.NodeDAO; import it.inaf.oats.vospace.persistence.model.Location; Loading @@ -15,12 +19,14 @@ 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.ExecutionPhase; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.ResultReference; 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 @@ -57,7 +63,8 @@ public class UriService { results.add(result); job.setResults(results); job.setPhase(ExecutionPhase.COMPLETED); // Moved phase setting to caller method for ERROR management // job.setPhase(ExecutionPhase.COMPLETED); } public void setSyncTransferEndpoints(JobSummary job) { Loading @@ -68,7 +75,8 @@ public class UriService { if (!"ivo://ivoa.net/vospace/core#httpget".equals(protocol.getUri()) && !"ivo://ivoa.net/vospace/core#httpput".equals(protocol.getUri())) { throw new IllegalStateException("Unsupported protocol " + protocol.getUri()); // throw new IllegalStateException("Unsupported protocol " + protocol.getUri()); throw new ProtocolNotSupportedException(protocol.getUri()); } protocol.setEndpoint(getEndpoint(job, transfer)); } Loading @@ -79,6 +87,35 @@ public class UriService { 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()); switch (jobType) { case pushToVoSpace: case pullToVoSpace: if (!NodeUtils.checkIfWritable(node, creator, groups)) { throw new PermissionDeniedException(relativePath); } break; case pullFromVoSpace: if (!NodeUtils.checkIfReadable(node, creator, groups)) { throw new PermissionDeniedException(relativePath); } break; default: throw new InternalFaultException("No job direction specified"); } if (NodeUtils.getIsBusy(node)) { throw new NodeBusyException(relativePath); } Location location = locationDAO.getNodeLocation(relativePath).orElse(null); String endpoint; Loading
src/main/java/it/inaf/oats/vospace/exception/DuplicateNodeException.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.CONFLICT) public class DuplicateNodeException extends VoSpaceException { public class DuplicateNodeException extends VoSpaceErrorSummarizableException { public DuplicateNodeException(String path) { super("Duplicate Node at path: " + path); super("Duplicate Node at path: " + path, ErrorSummaryFactory.VOSpaceFault.DUPLICATE_NODE); } }
src/main/java/it/inaf/oats/vospace/exception/InternalFaultException.java +6 −3 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import net.ivoa.xml.uws.v1.ErrorSummaryFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) // Status code 500 public class InternalFaultException extends VoSpaceException { public class InternalFaultException extends VoSpaceErrorSummarizableException { private static final Logger LOG = LoggerFactory.getLogger(InternalFaultException.class); public InternalFaultException(String msg) { super("InternalFaultException: " + msg); super("InternalFaultException: " + msg, ErrorSummaryFactory.VOSpaceFault.INTERNAL_FAULT); } public InternalFaultException(Throwable cause) { super("InternalFaultException: " + getMessage(cause)); super("InternalFaultException: " + getMessage(cause), ErrorSummaryFactory.VOSpaceFault.INTERNAL_FAULT); } private static String getMessage(Throwable cause) { Loading