Skip to content
FileDAO.java 5.9 KiB
Newer Older
Sonia Zorba's avatar
Sonia Zorba committed
/*
 * This file is part of vospace-file-service
 * Copyright (C) 2021 Istituto Nazionale di Astrofisica
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
Sonia Zorba's avatar
Sonia Zorba committed
package it.inaf.ia2.transfer.persistence;

import it.inaf.ia2.transfer.controller.FileInfo;
import java.nio.file.Path;
Sonia Zorba's avatar
Sonia Zorba committed
import java.sql.Array;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
Sonia Zorba's avatar
Sonia Zorba committed
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Sonia Zorba's avatar
Sonia Zorba committed
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class FileDAO {

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

Sonia Zorba's avatar
Sonia Zorba committed
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public FileDAO(DataSource fileCatalogDatasource) {
        this.jdbcTemplate = new JdbcTemplate(fileCatalogDatasource);
    }

    public Optional<FileInfo> getFileInfo(String virtualPath) {

Sonia Zorba's avatar
Sonia Zorba committed
        String sql = "SELECT n.node_id, is_public, group_read, group_write, creator_id, async_trans,\n"
                + "content_type, content_encoding, content_length, content_md5,\n"
                + "accept_views, provide_views, l.location_type, n.path <> n.relative_path AS virtual_parent,\n"
Sonia Zorba's avatar
Sonia Zorba committed
                + "(SELECT user_name FROM users WHERE user_id = creator_id) AS username,\n"
                + "base_path, os_path\n"
                + "FROM node_path p\n"
                + "JOIN node n ON p.node_id = n.node_id\n"
                + "JOIN location l ON (n.location_id IS NOT NULL AND n.location_id = l.location_id) OR (n.location_id IS NULL AND l.location_id = ?)\n"
                + "LEFT JOIN storage s ON s.storage_id = l.storage_dest_id\n"
                + "WHERE p.vos_path = ?";
Sonia Zorba's avatar
Sonia Zorba committed

        FileInfo fileInfo = jdbcTemplate.query(conn -> {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, uploadLocationId);
            ps.setString(2, virtualPath);
Sonia Zorba's avatar
Sonia Zorba committed
            return ps;
        }, rs -> {
            if (rs.next()) {
                FileInfo fi = new FileInfo();
                fi.setNodeId(rs.getInt("node_id"));
Sonia Zorba's avatar
Sonia Zorba committed
                fi.setIsPublic(rs.getBoolean("is_public"));
                fi.setGroupRead(toList(rs.getArray("group_read")));
                fi.setGroupWrite(toList(rs.getArray("group_write")));
Sonia Zorba's avatar
Sonia Zorba committed
                fi.setOwnerId(rs.getString("creator_id"));
Sonia Zorba's avatar
Sonia Zorba committed
                fi.setAsyncTrans(rs.getBoolean("async_trans"));
                fi.setAcceptViews(toList(rs.getArray("accept_views")));
                fi.setProvideViews(toList(rs.getArray("provide_views")));
                fi.setVirtualParent(rs.getBoolean("virtual_parent"));
                fi.setVirtualPath(virtualPath);
                fi.setContentEncoding(rs.getString("content_encoding"));
                fi.setContentLength(rs.getLong("content_length"));
                fi.setContentMd5(rs.getString("content_md5"));
                fi.setContentType(rs.getString("content_type"));
Sonia Zorba's avatar
Sonia Zorba committed
                return fi;
            }
            return null;
        });

        return Optional.ofNullable(fileInfo);
    }

    private void fillOsPath(FileInfo fi, ResultSet rs) throws SQLException {

        if (fi.getProvideViews() != null) {
            for (String provideView : fi.getProvideViews()) {
                if ("urn:list-of-files".equals(provideView)) {
                    // Not a physical file
                    return;
                }
            }
        }

        String basePath = rs.getString("base_path");
        String osPath = rs.getString("os_path");
        if (osPath.startsWith("/")) {
            osPath = osPath.substring(1);
        }

        Path completeOsPath = Path.of(basePath);

        boolean asyncLocation = "async".equals(rs.getString("location_type"));

        if (asyncLocation) {
            String username = rs.getString("username");
            completeOsPath = completeOsPath.resolve(username).resolve("retrieve");
        } else if (fi.hasVirtualParent()) {
            completeOsPath = completeOsPath.resolve(fi.getOwnerId());
        }

        completeOsPath = completeOsPath.resolve(osPath);
        fi.setOsPath(completeOsPath.toString());
    }

Sonia Zorba's avatar
Sonia Zorba committed
    private List<String> toList(Array array) throws SQLException {
        if (array == null) {
            return new ArrayList<>();
        }
        return Arrays.asList((String[]) array.getArray());
    }

    public void setBusy(int nodeId, boolean busy) {

        String sql = "UPDATE node SET busy_state = ? WHERE node_id = ?";

        jdbcTemplate.update(conn -> {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setBoolean(1, busy);
            ps.setInt(2, nodeId);
            return ps;
        });
    }

    public void setOsName(int nodeId, String newName) {

        String sql = "UPDATE node SET os_name = ? WHERE node_id = ?";

        jdbcTemplate.update(conn -> {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, newName);
            ps.setInt(2, nodeId);
            return ps;
        });
    }

    public void updateFileAttributes(int nodeId,
            String contentType,
            String contentEncoding,
            Long contentLength,
            String contentMd5) {

        String sql = "UPDATE node SET content_type = ?, content_encoding = ?, content_length = ?, content_md5 = ?, location_id = ? "
                + "WHERE node_id = ?";

        jdbcTemplate.update(conn -> {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, contentType);
            ps.setString(2, contentEncoding);
            ps.setLong(3, contentLength);
            ps.setString(4, contentMd5);
            ps.setInt(5, uploadLocationId);
            ps.setInt(6, nodeId);
Sonia Zorba's avatar
Sonia Zorba committed
}