/* * 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 getNodeLocation(String vosPath) { 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" + "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 getLocation(ResultSet rs, Supplier exceptionSupplier) throws SQLException { List locations = getLocations(rs); if (locations.isEmpty()) { return Optional.empty(); } if (locations.size() > 1) { throw exceptionSupplier.get(); } return Optional.of(locations.get(0)); } private List getLocations(ResultSet rs) throws SQLException { Map storagesMap = new HashMap<>(); Map 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()); } }