Skip to content
FileServiceClient.java 4.22 KiB
Newer Older
/*
 * This file is part of vospace-rest
 * Copyright (C) 2021 Istituto Nazionale di Astrofisica
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package it.inaf.oats.vospace;

import com.fasterxml.jackson.databind.ObjectMapper;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.Views;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import java.io.OutputStream;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.vospace.v2.Transfer;
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.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class FileServiceClient {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Value("${vospace-authority}")
    private String authority;

    @Value("${file-service-url}")
    private String fileServiceUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private HttpServletRequest request;

    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);

        String viewUri = transfer.getView().getUri();

        // Generate list of paths using view include parameters
        List<String> vosPaths = transfer.getView().getParam().stream()
                .map(p -> {
                    if (p.getUri().equals(viewUri + "/include")) {
                        if (p.getValue().contains("../")) {
                            throw new InvalidArgumentException("Relative paths are not supported");
                        }
                        return target + "/" + p.getValue();
                    } else {
                        throw new InvalidArgumentException("Unsupported view parameter: " + p.getUri());
                    }
                })
                .collect(Collectors.toList());

        if (vosPaths.isEmpty()) {
            // Add target path
            vosPaths.add(target.substring("vos://".length() + authority.length()));
        }

        ArchiveRequest archiveRequest = new ArchiveRequest();
        archiveRequest.setJobId(jobId);
        archiveRequest.setPaths(vosPaths);
        archiveRequest.setType(archiveTypeFromViewUri(transfer.getView().getUri()));

        String url = fileServiceUrl + "/archive";

        String token = ((User) request.getUserPrincipal()).getAccessToken();

        return restTemplate.execute(url, HttpMethod.POST, req -> {
            HttpHeaders headers = req.getHeaders();
            if (token != null) {
                headers.setBearerAuth(token);
            }
            headers.setContentType(MediaType.APPLICATION_JSON);
            try ( OutputStream os = req.getBody()) {
                MAPPER.writeValue(os, archiveRequest);
            }
        }, res -> {
            return res.getHeaders().getLocation().toString();
        }, new Object[]{});
    }

    private static class ArchiveRequest {

        private String type;
        private String jobId;
        private List<String> paths;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getJobId() {
            return jobId;
        }

        public void setJobId(String jobId) {
            this.jobId = jobId;
        }

        public List<String> getPaths() {
            return paths;
        }

        public void setPaths(List<String> paths) {
            this.paths = paths;
        }
    }

    private static String archiveTypeFromViewUri(String viewUri) {
        switch (viewUri) {
                return "ZIP";
            default:
                throw new IllegalArgumentException("Archive type not defined for " + viewUri);
        }
    }
}