Skip to content
LocationDAO.java 3.77 KiB
Newer Older
Sonia Zorba's avatar
Sonia Zorba committed
/*
 * 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.persistence;

import it.inaf.oats.vospace.persistence.model.Location;
import it.inaf.oats.vospace.persistence.model.LocationType;
import it.inaf.oats.vospace.persistence.model.Storage;
import it.inaf.oats.vospace.persistence.model.StorageType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class LocationDAO {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public LocationDAO(DataSource dataSource) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public Optional<Location> getNodeLocation(String vosPath) {

Sonia Zorba's avatar
Sonia Zorba committed
        String sql = "SELECT l.location_id, location_type, storage_src_id, storage_dest_id,\n"
                + "storage_id, storage_type, base_path, base_url, hostname\n"
                + "FROM location l\n"
                + "JOIN storage s ON l.storage_src_id = s.storage_id OR l.storage_dest_id = s.storage_id\n"
Sonia Zorba's avatar
Sonia Zorba committed
                + "JOIN node n ON n.location_id = l.location_id\n"
                + "WHERE n.node_id = id_from_vos_path(?)\n"
                + "AND storage_type <> 'cold'";

        return jdbcTemplate.query(sql, ps -> {
            ps.setString(1, vosPath);
        }, rs -> {
            return getLocation(rs, () -> new IllegalStateException("Found multiple locations for the same vos_path"));
        });
    }

    private Optional<Location> getLocation(ResultSet rs, Supplier<IllegalStateException> exceptionSupplier) throws SQLException {
        List<Location> locations = getLocations(rs);
        if (locations.isEmpty()) {
            return Optional.empty();
        }
        if (locations.size() > 1) {
            throw exceptionSupplier.get();
        }
        return Optional.of(locations.get(0));
    }

    private List<Location> getLocations(ResultSet rs) throws SQLException {

        Map<Integer, Storage> storagesMap = new HashMap<>();
        Map<Integer, Location> locationsMap = new HashMap<>();

        while (rs.next()) {
            int locationId = rs.getInt("location_id");
            Location location = locationsMap.get(locationId);
            if (location == null) {
                location = new Location();
                location.setId(locationId);
                locationsMap.put(locationId, location);
            }
            location.setType(LocationType.parse(rs.getString("location_type")));

            int storageId = rs.getInt("storage_id");
            Storage storage = storagesMap.get(storageId);
            if (storage == null) {
                storage = new Storage();
                storage.setId(storageId);
                storagesMap.put(storageId, storage);
            }

            storage.setType(StorageType.parse(rs.getString("storage_type")));
            storage.setBasePath(rs.getString("base_path"));
            storage.setBaseUrl(rs.getString("base_url"));
            storage.setHostname(rs.getString("hostname"));

            Storage storageSrc = storagesMap.get(rs.getInt("storage_src_id"));
            if (storageSrc != null) {
                location.setSource(storageSrc);
            }
            Storage storageDest = storagesMap.get(rs.getInt("storage_dest_id"));
            if (storageDest != null) {
                location.setDestination(storageDest);
            }
        }

        return new ArrayList<>(locationsMap.values());
    }
}