Skip to content
Snippets Groups Projects
Commit e28aa4c6 authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

Merge origin/master into copyNode

parents 1bb3fa27 7a9d688e
Branches
Tags
No related merge requests found
Showing
with 93 additions and 74 deletions
......@@ -41,12 +41,7 @@ public class FileServiceClient {
public String startArchiveJob(Transfer transfer, String jobId) {
if (transfer.getTarget().size() != 1) {
throw new IllegalArgumentException("Target size is " + transfer.getTarget().size());
}
String target = transfer.getTarget().get(0)
.substring("vos://".length() + authority.length());
String target = transfer.getTarget().substring("vos://".length() + authority.length());
String viewUri = transfer.getView().getUri();
......
......@@ -6,6 +6,7 @@
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.InternalFaultException;
import it.inaf.oats.vospace.persistence.JobDAO;
import net.ivoa.xml.uws.v1.ExecutionPhase;
......@@ -17,6 +18,7 @@ import it.inaf.oats.vospace.exception.InvalidArgumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import it.inaf.oats.vospace.exception.VoSpaceErrorSummarizableException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import javax.servlet.http.HttpServletRequest;
......@@ -96,7 +98,7 @@ public class JobService {
Transfer transfer = uriService.getTransfer(job);
ExecutionPhase phase;
if (transfer.getProtocols().stream().anyMatch(p -> "ia2:async-recall".equals(p.getUri()))) {
if (isAsyncRecall(transfer)) {
// Async recall from tape jobs are queued. They will be started by VOSpace transfer service
phase = ExecutionPhase.QUEUED;
} else {
......@@ -138,16 +140,15 @@ public class JobService {
private Transfer handlePullToVoSpace(JobSummary job, Transfer transfer) {
for (Protocol protocol : transfer.getProtocols()) {
switch (protocol.getUri()) {
case "ia2:async-recall":
if (isAsyncRecall(transfer)) {
asyncTransfService.startJob(job);
return transfer;
case "ivo://ivoa.net/vospace/core#httpget":
if (transfer.getTarget().size() != 1) {
throw new InvalidArgumentException("Invalid target size for pullToVoSpace: " + transfer.getTarget().size());
}
String nodeUri = transfer.getTarget().get(0);
for (Protocol protocol : transfer.getProtocols()) {
switch (protocol.getUri()) {
case "ivo://ivoa.net/vospace/core#httpget":
String nodeUri = transfer.getTarget();
String contentUri = protocol.getEndpoint();
uriService.setNodeRemoteLocation(nodeUri, contentUri);
Transfer negotiatedTransfer = uriService.getNegotiatedTransfer(job, transfer);
......@@ -164,6 +165,11 @@ public class JobService {
throw new InvalidArgumentException("Transfer contains no protocols");
}
private boolean isAsyncRecall(Transfer transfer) {
return transfer.getView() != null
&& Views.ASYNC_RECALL_VIEW_URI.equals(transfer.getView().getUri());
}
private void handleMoveNode(JobSummary jobSummary, Transfer transfer) {
// User data must be extracted before starting the new thread
// to avoid the "No thread-bound request found" exception
......@@ -222,8 +228,9 @@ public class JobService {
* compliance with specifications
*
*/
public void createSyncJobResult(JobSummary job) {
public Optional<VoSpaceErrorSummarizableException> createSyncJobResult(JobSummary job) {
Transfer negotiatedTransfer = null;
VoSpaceErrorSummarizableException exception = null;
try {
Transfer transfer = uriService.getTransfer(job);
negotiatedTransfer = uriService.getNegotiatedTransfer(job, transfer);
......@@ -234,14 +241,16 @@ public class JobService {
job.setPhase(ExecutionPhase.ERROR);
stripProtocols(job, negotiatedTransfer);
job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(e));
exception = e;
} catch (Exception e) {
job.setPhase(ExecutionPhase.ERROR);
stripProtocols(job, negotiatedTransfer);
job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(
new InternalFaultException(e)));
exception = new InternalFaultException(e);
job.setErrorSummary(ErrorSummaryFactory.newErrorSummary(exception));
} finally {
jobDAO.createJob(job, negotiatedTransfer);
}
return Optional.ofNullable(exception);
}
private void stripProtocols(JobSummary job, Transfer negotiatedTransfer) {
......@@ -265,7 +274,7 @@ public class JobService {
case pushToVoSpace:
ResultReference dataNodeRef = new ResultReference();
dataNodeRef.setId("dataNode");
dataNodeRef.setHref(transfer.getTarget().get(0));
dataNodeRef.setHref(transfer.getTarget());
jobSummary.getResults().add(dataNodeRef);
break;
}
......
......@@ -8,7 +8,6 @@ package it.inaf.oats.vospace;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.exception.InternalFaultException;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
......@@ -33,12 +32,8 @@ public class MoveService extends AbstractNodeService {
@Transactional(rollbackFor = { Exception.class }, isolation = Isolation.REPEATABLE_READ)
public void processMoveJob(Transfer transfer, User user) {
if (transfer.getTarget().size() != 1) {
throw new InvalidArgumentException("Invalid target size for moveNode: " + transfer.getTarget().size());
}
// Get Source Vos Path
String sourcePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget().get(0), authority);
String sourcePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget(), authority);
// Get Destination Vos Path (it's in transfer direction)
String destinationPath = URIUtils.returnVosPathFromNodeURI(transfer.getDirection(), authority);
......
......@@ -81,7 +81,7 @@ public class TransferController {
@RequestParam("DIRECTION") String direction, @RequestParam("PROTOCOL") String protocolUris, User principal) {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList(target));
transfer.setTarget(target);
transfer.setDirection(direction);
// CADC client sends multiple protocol parameters and Spring join them using a comma separator.
......@@ -93,16 +93,12 @@ public class TransferController {
}
JobSummary jobSummary = newJobSummary(transfer, principal);
jobService.createSyncJobResult(jobSummary);
if (jobSummary.getErrorSummary() != null) {
// TODO: decide how to hanlde HTTP error codes
jobService.createSyncJobResult(jobSummary).ifPresent(ex -> {
// If an error occurs with the synchronous convenience mode where the preferred endpoint
// is immediately returned as a redirect, the error information is returned directly in
// the response body with the associated HTTP status code.
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(jobSummary.getErrorSummary().getMessage());
}
throw ex;
});
// Behaves as if REQUEST=redirect was set, for compatibility with CADC client
String endpoint = transfer.getProtocols().get(0).getEndpoint();
......
......@@ -144,13 +144,8 @@ public class UriService {
}
private String getEndpoint(JobSummary job, Transfer transfer) {
boolean isArchiveView = isArchiveView(transfer);
if (!isArchiveView && transfer.getTarget().size() != 1) {
throw new InvalidArgumentException("Invalid target size: " + transfer.getTarget().size());
}
String relativePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget().get(0), authority);
String relativePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget(), authority);
User user = (User) servletRequest.getUserPrincipal();
String creator = user.getName();
......@@ -183,7 +178,7 @@ public class UriService {
throw new NodeBusyException(relativePath);
}
if (isArchiveView) {
if (isArchiveView(transfer)) {
return fileServiceClient.startArchiveJob(transfer, job.getJobId());
}
......
......@@ -5,12 +5,13 @@
*/
package it.inaf.oats.vospace;
import it.inaf.oats.vospace.datamodel.Views;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.ivoa.xml.uws.v1.JobSummary;
import net.ivoa.xml.vospace.v2.Protocol;
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.fail;
import org.junit.jupiter.api.Test;
......@@ -26,7 +27,7 @@ import redis.clients.jedis.Jedis;
@ExtendWith(MockitoExtension.class)
public class AsyncTransferServiceTest {
private static final String JSON_JOB = "{\"jobId\":\"job_id\",\"runId\":null,\"ownerId\":null,\"phase\":null,\"quote\":null,\"creationTime\":null,\"startTime\":null,\"endTime\":null,\"executionDuration\":0,\"destruction\":null,\"parameters\":null,\"results\":[],\"errorSummary\":null,\"jobInfo\":{\"transfer\":{\"target\":[\"vos://example.com!vospace/my-node\"],\"direction\":\"pullToVoSpace\",\"view\":null,\"protocols\":[],\"keepBytes\":null,\"version\":null,\"param\":[]}},\"version\":null}\n";
private static final String JSON_JOB = "{\"jobId\":\"job_id\",\"runId\":null,\"ownerId\":null,\"phase\":null,\"quote\":null,\"creationTime\":null,\"startTime\":null,\"endTime\":null,\"executionDuration\":0,\"destruction\":null,\"parameters\":null,\"results\":[],\"errorSummary\":null,\"jobInfo\":{\"transfer\":{\"target\":\"vos://example.com!vospace/my-node\",\"direction\":\"pullToVoSpace\",\"view\":{\"param\":[{\"value\":\"file1.txt\",\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall/include\"},{\"value\":\"file2.txt\",\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall/include\"}],\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall\",\"original\":true},\"protocols\":[],\"keepBytes\":false,\"version\":null,\"param\":[]}},\"version\":null}";
@Test
public void testRedisRpc() {
......@@ -61,10 +62,23 @@ public class AsyncTransferServiceTest {
private JobSummary getFakeJob() {
Transfer transfer = new Transfer();
transfer.setDirection("pullToVoSpace");
Protocol protocol = new Protocol();
protocol.setUri("ia2:async-recall");
transfer.getProtocols().add(protocol);
transfer.setTarget(Arrays.asList("vos://example.com!vospace/my-node"));
transfer.setTarget("vos://example.com!vospace/my-node");
View view = new View();
view.setUri(Views.ASYNC_RECALL_VIEW_URI);
Param p1 = new Param();
p1.setUri(Views.ASYNC_RECALL_VIEW_URI + "/include");
p1.setValue("file1.txt");
view.getParam().add(p1);
Param p2 = new Param();
p2.setUri(Views.ASYNC_RECALL_VIEW_URI + "/include");
p2.setValue("file2.txt");
view.getParam().add(p2);
transfer.setView(view);
JobSummary job = new JobSummary();
job.setJobId("job_id");
......
......@@ -14,7 +14,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
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;
......@@ -89,7 +88,7 @@ public class FileServiceClientTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydir"));
transfer.setTarget("vos://example.com!vospace/mydir");
View view = new View();
view.setUri(Views.ZIP_VIEW_URI);
transfer.setView(view);
......@@ -105,7 +104,7 @@ public class FileServiceClientTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir"));
transfer.setTarget("vos://example.com!vospace/parent_dir");
View view = new View();
view.setUri(Views.TAR_VIEW_URI);
transfer.setView(view);
......@@ -123,7 +122,7 @@ public class FileServiceClientTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir"));
transfer.setTarget("vos://example.com!vospace/parent_dir");
View view = new View();
view.setUri(Views.TAR_VIEW_URI);
transfer.setView(view);
......@@ -140,7 +139,7 @@ public class FileServiceClientTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir"));
transfer.setTarget("vos://example.com!vospace/parent_dir");
View view = new View();
view.setUri(viewUri);
transfer.setView(view);
......
......@@ -5,16 +5,17 @@
*/
package it.inaf.oats.vospace;
import it.inaf.oats.vospace.datamodel.Views;
import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.persistence.JobDAO;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
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.vospace.v2.View;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
......@@ -218,7 +219,7 @@ public class JobServiceTest {
private Transfer getPullFromVoSpaceHttpTransfer() {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/myfile"));
transfer.setTarget("vos://example.com!vospace/myfile");
transfer.setDirection("pullFromVoSpace");
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
......@@ -229,9 +230,9 @@ public class JobServiceTest {
private Transfer getTapeTransfer() {
Transfer transfer = new Transfer();
transfer.setDirection("pullToVoSpace");
Protocol protocol = new Protocol();
protocol.setUri("ia2:async-recall");
transfer.getProtocols().add(protocol);
View view = new View();
view.setUri(Views.ASYNC_RECALL_VIEW_URI);
transfer.setView(view);
return transfer;
}
......
......@@ -11,7 +11,6 @@ import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton;
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import net.ivoa.xml.vospace.v2.Transfer;
......@@ -209,7 +208,7 @@ public class MoveServiceTest {
private Transfer getTransfer(String vosTarget, String vosDestination) {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://" + this.authority + vosTarget));
transfer.setTarget("vos://" + this.authority + vosTarget);
transfer.setDirection("vos://" + this.authority + vosDestination);
return transfer;
}
......
......@@ -11,6 +11,7 @@ import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.datamodel.Views;
import it.inaf.oats.vospace.exception.ErrorSummaryFactory;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.exception.ProtocolNotSupportedException;
import it.inaf.oats.vospace.persistence.JobDAO;
import it.inaf.oats.vospace.persistence.LocationDAO;
import it.inaf.oats.vospace.persistence.NodeDAO;
......@@ -22,7 +23,6 @@ import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Optional;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import net.ivoa.xml.uws.v1.JobSummary;
......@@ -428,6 +428,20 @@ public class TransferControllerTest {
.andExpect(status().is3xxRedirection());
}
@Test
public void testSyncTransferUrlParamsModeUnsupportedProtocol() throws Exception {
Exception ex = mockMvc.perform(get("/synctrans")
.header("Authorization", "Bearer user1_token")
.param("TARGET", "vos://example.com!vospace/mynode")
.param("DIRECTION", "pullFromVoSpace")
.param("PROTOCOL", "ivo://ivoa.net/vospace/core#httpput"))
.andExpect(status().isBadRequest())
.andReturn().getResolvedException();
assertTrue(ex instanceof ProtocolNotSupportedException);
}
private Jobs getFakeJobs() {
Jobs jobs = new Jobs();
jobs.setVersion("1.1");
......@@ -458,7 +472,7 @@ public class TransferControllerTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mynode"));
transfer.setTarget("vos://example.com!vospace/mynode");
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
transfer.getProtocols().add(protocol);
......
......@@ -17,7 +17,6 @@ import it.inaf.oats.vospace.persistence.LocationDAO;
import it.inaf.oats.vospace.persistence.NodeDAO;
import it.inaf.oats.vospace.persistence.model.Location;
import it.inaf.oats.vospace.persistence.model.LocationType;
import java.util.Arrays;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.JobSummary;
......@@ -298,7 +297,7 @@ public class UriServiceTest {
mockPublicNode();
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1"));
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection("pullFromVoSpace");
Protocol protocol1 = new Protocol();
......@@ -338,7 +337,7 @@ public class UriServiceTest {
when(servletRequest.getUserPrincipal()).thenReturn(user);
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1"));
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection("pushToVoSpace");
Protocol protocol1 = new Protocol();
......@@ -367,7 +366,7 @@ public class UriServiceTest {
public void testSetSyncTransferEndpointsUnsupportedProtocol() {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1"));
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection("pullFromVoSpace");
Protocol protocol = new Protocol();
......@@ -390,7 +389,7 @@ public class UriServiceTest {
public void testSetSyncTransferEndpointsNoProtocols() {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1"));
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection("pullFromVoSpace");
JobSummary job = new JobSummary();
......@@ -420,7 +419,7 @@ public class UriServiceTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/file1"));
transfer.setTarget("vos://example.com!vospace/file1");
JobSummary job = new JobSummary();
JobSummary.JobInfo jobInfo = new JobSummary.JobInfo();
......@@ -440,7 +439,7 @@ public class UriServiceTest {
Transfer transfer = new Transfer();
transfer.setDirection("pullFromVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/parent_dir"));
transfer.setTarget("vos://example.com!vospace/parent_dir");
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
transfer.getProtocols().add(protocol);
......@@ -492,7 +491,7 @@ public class UriServiceTest {
private JobSummary getJob() {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1"));
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection(JobService.JobDirection.pullFromVoSpace.toString());
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
......@@ -511,7 +510,7 @@ public class UriServiceTest {
private JobSummary getPushToVoSpaceJob() {
Transfer transfer = new Transfer();
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mydata1/mydata2"));
transfer.setTarget("vos://example.com!vospace/mydata1/mydata2");
transfer.setDirection(JobService.JobDirection.pushToVoSpace.toString());
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpput");
......
......@@ -29,7 +29,6 @@ import net.ivoa.xml.uws.v1.ErrorSummary;
import net.ivoa.xml.uws.v1.Jobs;
import it.inaf.oats.vospace.exception.ErrorSummaryFactory;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import java.util.Arrays;
import net.ivoa.xml.uws.v1.ResultReference;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
......@@ -51,7 +50,7 @@ public class JobDAOTest {
private JobSummary getJob() {
Transfer transfer = new Transfer();
transfer.setDirection("pushToVoSpace");
transfer.setTarget(Arrays.asList("vos://example.com!vospace/mynode"));
transfer.setTarget("vos://example.com!vospace/mynode");
JobSummary job = new JobSummary();
job.setJobId("123");
......
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
<vos:target>vos://example.com!vospace/mynode</vos:target>
<vos:direction>pullToVoSpace</vos:direction>
<vos:protocol uri="ia2:async-recall" />
<vos:view uri="ivo://ia2.inaf.it/vospace/views#async-recall">
<vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test1.txt</vos:param>
<vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test2.txt</vos:param>
<vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test3.txt</vos:param>
</vos:view>
</vos:transfer>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment