Commit 330ec0de authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

Task #3637 - Added node generation for pushTo/pullTo operations in case

it doesn't exist
parent b0f23cd8
Loading
Loading
Loading
Loading
+31 −7
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ 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.InvalidURIException;
import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.exception.ProtocolNotSupportedException;
@@ -19,14 +20,13 @@ 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.JobSummary;
import net.ivoa.xml.uws.v1.ResultReference;
import net.ivoa.xml.vospace.v2.DataNode;
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;
@@ -54,6 +54,9 @@ public class UriService {
    @Autowired
    private ServletRapClient rapClient;

    @Autowired
    private CreateNodeController createNodeController;

    public void setTransferJobResult(JobSummary job, Transfer transfer) {

        List<ResultReference> results = new ArrayList<>();
@@ -81,18 +84,39 @@ public class UriService {
        protocol.setEndpoint(getEndpoint(job, transfer));
    }

    private Node getEndpointNode(String relativePath,
            JobService.JobType jobType,
            User user) {
        Optional<Node> optNode = nodeDao.listNode(relativePath);
        if (optNode.isPresent()) {            
            return optNode.get();
        } else {
            switch (jobType) {
                case pullFromVoSpace:
                    throw new NodeNotFoundException(relativePath);
                case pushToVoSpace:
                case pullToVoSpace:
                    DataNode newNode = new DataNode();
                    newNode.setUri(relativePath);
                    return createNodeController.createNode(newNode, user);                     
                default:
                    throw new InternalFaultException("No supported job direction specified");
            }

        }
    }

    private String getEndpoint(JobSummary job, Transfer transfer) {

        String relativePath = transfer.getTarget().substring("vos://".length() + authority.length());

        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());
        Node node = this.getEndpointNode(relativePath, jobType, user);

        switch (jobType) {
            case pushToVoSpace:
@@ -109,7 +133,7 @@ public class UriService {
                break;

            default:
                throw new InternalFaultException("No job direction specified");
                throw new InternalFaultException("No supported job direction specified");
        }

        if (NodeUtils.getIsBusy(node)) {
+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.NOT_FOUND)
public class ContainerNotFoundException extends VoSpaceException {
public class ContainerNotFoundException extends VoSpaceErrorSummarizableException {

    public ContainerNotFoundException(String path) {
        super("Container Not Found at path: " + path);
        super("Container Not Found at path: " + path, 
                ErrorSummaryFactory.VOSpaceFault.NODE_NOT_FOUND);
    }
}
+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.BAD_REQUEST)
public class LinkFoundException extends VoSpaceException {
public class LinkFoundException extends VoSpaceErrorSummarizableException {

    public LinkFoundException(String path) {
        super("Link Found at path: " + path);
        super("Link Found at path: " + path, 
                ErrorSummaryFactory.VOSpaceFault.INVALID_URI);
    }
}
+74 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ import it.inaf.oats.vospace.persistence.model.LocationType;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.JobSummary;
import net.ivoa.xml.vospace.v2.ContainerNode;
import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Property;
@@ -21,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.springframework.beans.factory.annotation.Autowired;
@@ -46,6 +48,9 @@ public class UriServiceTest {
    @MockBean
    private ServletRapClient rapClient;
    
    @MockBean
    private CreateNodeController createNodeController;

    @Autowired
    private HttpServletRequest servletRequest;

@@ -124,6 +129,59 @@ public class UriServiceTest {
        assertEquals("http://file-service/mydata1?jobId=job-id&token=<new-token>", job.getResults().get(0).getHref());
    }
    
    @Test
    public void pushToNonexistentNode() {
        
        ContainerNode node = new ContainerNode();
        node.setUri("vos://example.com!vospace/mydata1");
        Property creator = new Property();
        creator.setUri(NodeProperties.CREATOR_URI);
        creator.setValue("user1");
        node.getProperties().add(creator);
        
        Property readgroup = new Property();
        readgroup.setUri(NodeProperties.GROUP_READ_URI);
        readgroup.setValue("group1");
        node.getProperties().add(readgroup);
        
        DataNode dnode = new DataNode();
        dnode.setUri("vos://example.com!vospace/mydata1/mydata2");
        dnode.getProperties().add(creator);
        dnode.getProperties().add(readgroup);
        
        Property writegroup = new Property();
        writegroup.setUri(NodeProperties.GROUP_WRITE_URI);
        writegroup.setValue("group1");
        dnode.getProperties().add(writegroup);
                
        when(nodeDAO.listNode(eq("/mydata1"))).thenReturn(Optional.of(node));
        when(nodeDAO.listNode(eq("/mydata1/mydata2"))).thenReturn(Optional.empty());
               
        
        User user = mock(User.class);
        when(user.getAccessToken()).thenReturn("<token>");
        when(user.getName()).thenReturn("user1");
        
        when(servletRequest.getUserPrincipal()).thenReturn(user);

        when(rapClient.exchangeToken(argThat(req -> {
            assertEquals("<token>", req.getSubjectToken());
            assertEquals("http://file-service/mydata1/mydata2", req.getResource());
            return true;
        }), any())).thenReturn("<new-token>");

        JobSummary job = getPushToVoSpaceJob();
        Transfer tr = uriService.getTransfer(job);
        
        when(createNodeController.createNode(any(), eq(user))).thenReturn(dnode);
        
        uriService.setTransferJobResult(job, tr);
        
        verify(createNodeController, times(1)).createNode(any(), eq(user));
        
        assertEquals("http://file-service/mydata1/mydata2?jobId=job-id2&token=<new-token>", job.getResults().get(0).getHref());    
    }

    @Test
    public void setNodeRemoteLocationTest() {

@@ -156,4 +214,20 @@ public class UriServiceTest {

        return job;
    }
    
    private JobSummary getPushToVoSpaceJob() {
        Transfer transfer = new Transfer();
        transfer.setTarget("vos://example.com!vospace/mydata1/mydata2");
        transfer.setDirection(JobService.JobType.pushToVoSpace.toString());

        JobSummary job = new JobSummary();
        job.setJobId("job-id2");

        JobSummary.JobInfo jobInfo = new JobSummary.JobInfo();
        jobInfo.getAny().add(transfer);

        job.setJobInfo(jobInfo);

        return job;        
    }
}