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

Established expected input

parent f1868148
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@
package it.inaf.ia2.transfer.controller;

import it.inaf.ia2.transfer.auth.TokenPrincipal;
import it.inaf.ia2.transfer.exception.PermissionDeniedException;
import it.inaf.ia2.transfer.service.ArchiveJob;
import it.inaf.ia2.transfer.service.ArchiveJob.Type;
import it.inaf.ia2.transfer.service.ArchiveService;
+5 −1
Original line number Diff line number Diff line
@@ -10,10 +10,14 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import it.inaf.ia2.transfer.service.CopyService;

@RestController
public class CopyController extends AuthenticatedFileController {

    @Autowired
    private CopyService copyService;

    @PostMapping(value = "/copy", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> copyFiles(@RequestBody CopyRequest copyRequest) {
+10 −10
Original line number Diff line number Diff line
@@ -8,8 +8,8 @@ package it.inaf.ia2.transfer.controller;
public class CopyRequest {

    String jobId;
    String target;
    String direction;
    String sourceRootVosPath;
    String destinationRootVosPath;

    public String getJobId() {
        return jobId;
@@ -19,20 +19,20 @@ public class CopyRequest {
        this.jobId = jobId;
    }

    public String getTarget() {
        return target;
    public String getSourceRootVosPath() {
        return sourceRootVosPath;
    }

    public void setTarget(String target) {
        this.target = target;
    public void setSourceRootVosPath(String sourceRootVosPath) {
        this.sourceRootVosPath = sourceRootVosPath;
    }

    public String getDirection() {
        return direction;
    public String getDestinationRootVosPath() {
        return destinationRootVosPath;
    }

    public void setDirection(String direction) {
        this.direction = direction;
    public void setDestinationRootVosPath(String destinationRootVosPath) {
        this.destinationRootVosPath = destinationRootVosPath;
    }

}
+153 −0
Original line number Diff line number Diff line
/*
 * This file is part of vospace-file-service
 * Copyright (C) 2021 Istituto Nazionale di Astrofisica
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package it.inaf.ia2.transfer.service;

import it.inaf.ia2.transfer.auth.TokenPrincipal;
import it.inaf.ia2.transfer.exception.InsufficientStorageException;
import it.inaf.ia2.transfer.exception.JobException;
import it.inaf.ia2.transfer.exception.JobException.Type;
import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.JobDAO;
import it.inaf.ia2.transfer.persistence.LocationDAO;
import it.inaf.ia2.transfer.persistence.model.FileInfo;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.security.Principal;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import org.kamranzafar.jtar.TarEntry;
import org.kamranzafar.jtar.TarOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.unit.DataSize;
import org.springframework.web.client.RestTemplate;

@Service
public class CopyService {

    private static final Logger LOG = LoggerFactory.getLogger(CopyService.class);

    @Autowired
    private FileDAO fileDAO;

    @Autowired
    private LocationDAO locationDAO;

    @Autowired
    private JobDAO jobDAO;

    @Autowired
    private AuthorizationService authorizationService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${upload_location_id}")
    private int uploadLocationId;

    // Maximum size of the working directory for each registered user
    @Value("${generated.dir.max-size}")
    private DataSize generatedDirMaxSize;
    
    
    
    
    public void copyFiles(String sourceRootVosPath, 
            String destinationRootVosPath, String jobId) {
        // We use jobId to identify nodes created by the REST part of CopyNode
        // We expect them to be locked
        
                
        
        
    }

    

    private String getCommonParent(List<String> vosPaths) {
        String commonParent = null;
        for (String vosPath : vosPaths) {
            if (commonParent == null) {
                commonParent = vosPath;
            } else {
                StringBuilder newCommonParent = new StringBuilder();
                boolean same = true;
                for (int i = 0; same && i < Math.min(commonParent.length(), vosPath.length()); i++) {
                    if (commonParent.charAt(i) == vosPath.charAt(i)) {
                        newCommonParent.append(commonParent.charAt(i));
                    } else {
                        same = false;
                    }
                }
                commonParent = newCommonParent.toString();
            }
        }
        return commonParent;
    }

    private <O extends OutputStream, E> void downloadFileIntoArchive(FileInfo fileInfo, String relPath, TokenPrincipal tokenPrincipal, ArchiveHandler<O, E> handler, String baseUrl) {

        if (baseUrl == null) {
            LOG.error("Location URL not found for location " + fileInfo.getLocationId());
            throw new JobException(Type.FATAL, "Internal Fault")
                    .setErrorDetail("InternalFault: Unable to retrieve location of file " + fileInfo.getVirtualPath());
        }

        String url = baseUrl + "/" + fileInfo.getVirtualName();

        LOG.trace("Downloading file from " + url);

        restTemplate.execute(url, HttpMethod.GET, req -> {
            HttpHeaders headers = req.getHeaders();
            if (tokenPrincipal.getToken() != null) {
                headers.setBearerAuth(tokenPrincipal.getToken());
            }
        }, res -> {
            File tmpFile = Files.createTempFile("download", null).toFile();
            try ( FileOutputStream os = new FileOutputStream(tmpFile)) {
                res.getBody().transferTo(os);
                handler.putNextEntry(tmpFile, relPath);
                try ( FileInputStream is = new FileInputStream(tmpFile)) {
                    is.transferTo(handler.getOutputStream());
                }
            } finally {
                tmpFile.delete();
            }
            return null;
        }, new Object[]{});
    }

    private <O extends OutputStream, E> void writeFileIntoArchive(FileInfo fileInfo, String relPath, TokenPrincipal tokenPrincipal, ArchiveHandler<O, E> handler) throws IOException {
        if (!authorizationService.isDownloadable(fileInfo, tokenPrincipal)) {
            throw new JobException(Type.FATAL, "Permission Denied")
                    .setErrorDetail("PermissionDenied: " + fileInfo.getVirtualPath());
        }

        File file = new File(fileInfo.getOsPath());
        LOG.trace("Adding file " + file.getAbsolutePath() + " to tar archive");

        try ( InputStream is = new FileInputStream(file)) {
            handler.putNextEntry(file, relPath);
            is.transferTo(handler.getOutputStream());
        }
    }
}