catalogue-util-library/src/main/java/org/gcube/datacatalogue/utillibrary/db/DBCaller.java

293 lines
7.9 KiB
Java

package org.gcube.datacatalogue.utillibrary.db;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class DBCaller.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 9, 2021
*/
public class DBCaller {
private static final Logger LOG = LoggerFactory.getLogger(DBCaller.class);
private String ckanDBURL;
private Integer ckanDBPort;
private String ckanDBName;
private String ckanDBUser;
private String ckanDBPwd;
/**
* Instantiates a new DB caller.
*/
public DBCaller() {
}
/**
* Instantiates a new DB caller.
*
* @param ckanDBURL the ckan DBURL
* @param ckanDBPort the ckan DB port
* @param ckanDBName the ckan DB name
* @param ckanDBUser the ckan DB user
* @param ckanDBPwd the ckan DB pwd
*/
public DBCaller(String ckanDBURL, Integer ckanDBPort, String ckanDBName, String ckanDBUser,
String ckanDBPwd) {
this.ckanDBURL = ckanDBURL;
this.ckanDBPort = ckanDBPort;
this.ckanDBName = ckanDBName;
this.ckanDBUser = ckanDBUser;
this.ckanDBPwd = ckanDBPwd;
}
/**
* Retrieve connection from the pool.
*
* @return a connection available within the pool
* @throws SQLException the SQL exception
* @throws ClassNotFoundException the class not found exception
*/
private Connection getConnection() throws SQLException, ClassNotFoundException{
LOG.trace("CONNECTION REQUEST");
// create db connection
Class.forName("org.postgresql.Driver");
String dbBaseConnectionURL = String.format("jdbc:postgresql://%s", ckanDBURL);
if(ckanDBPort!=null)
dbBaseConnectionURL+=":" + ckanDBPort;
dbBaseConnectionURL+="/" + ckanDBName;
LOG.debug("DB CONNECTION URL: "+dbBaseConnectionURL);
LOG.debug("CKAN_DB_USER: "+ckanDBUser);
Connection connection = DriverManager.getConnection(dbBaseConnectionURL, ckanDBUser, ckanDBPwd);
LOG.trace("Returnig db connection");
return connection;
}
/**
* Retrieve the map (groups id, capacity) with the groups to which the user belongs by querying directly the database.
*
* @param username the username
* @return the groups by user from DB
*/
public Map<String, RolesCkanGroupOrOrg> getGroupsByUserFromDB(String username){
checkNotNull(username);
LOG.debug("Get groups by user called for username: "+username);
//couples (groups id, capacity) of the user in the group
Map<String, RolesCkanGroupOrOrg> toReturn = new HashMap<String, RolesCkanGroupOrOrg>();
Connection connection = null;
try{
String userId = getUserIdForUsername(username);
connection = getConnection();
String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" "
+ "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?"
+ " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;";
LOG.debug("Performing query: "+joinQuery);
PreparedStatement preparedStatement = connection.prepareStatement(joinQuery);
preparedStatement.setString(1, userId);
preparedStatement.setBoolean(2, false);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity")));
}
}catch(Exception e){
LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage());
return null;
}finally{
closeConnection(connection);
}
LOG.debug("returning map: "+toReturn);
return toReturn;
}
/**
* Gets the user id for username.
*
* @param username the username
* @return the user id for username
*/
private String getUserIdForUsername(String username) {
LOG.debug("Get user id for username called for username: "+username);
Connection connection = null;
String userId = null;
try{
connection = getConnection();
String selQuery = "SELECT \"id\" FROM \"public\".\"user\" WHERE \"name\"=?;";
LOG.debug("Performing query: "+selQuery);
PreparedStatement preparedStatement = connection.prepareStatement(selQuery);
preparedStatement.setString(1, username);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
userId = rs.getString("id");
break;
}
LOG.debug("For username "+username+" returning the user id: "+userId);
return userId;
}catch(Exception e){
LOG.error("Failed to retrieve the user id for username:"+username+". Error is " + e.getMessage());
return null;
}finally{
closeConnection(connection);
}
}
/**
* Retrieve the map (organisation id, capacity) with the organisations to which the user belongs by querying directly the database.
*
* @param username the username
* @return the organizations by user from DB
*/
public Map<String, RolesCkanGroupOrOrg> getOrganizationsByUserFromDB(String username){
LOG.debug("Get organisations by user called");
checkNotNull(username);
Map<String, RolesCkanGroupOrOrg> toReturn = new HashMap<String, RolesCkanGroupOrOrg>();
Connection connection = null;
try{
String userId = getUserIdForUsername(username);
connection = getConnection();
ResultSet rs;
String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" "
+ "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?"
+ " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;";
PreparedStatement preparedStatement = connection.prepareStatement(joinQuery);
preparedStatement.setString(1, userId);
preparedStatement.setBoolean(2, true);
rs = preparedStatement.executeQuery();
while (rs.next()) {
toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity")));
}
}catch(Exception e){
LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage());
return null;
}finally{
closeConnection(connection);
}
LOG.debug("returning map: "+toReturn);
return toReturn;
}
/**
* Gets the api key from username.
*
* @param username the username
* @param state the state
* @return the api key from username
*/
public String getApiKeyFromUsername(String username, String state) {
LOG.debug("Request api key for user = " + username);
// checks
checkNotNull(username);
checkArgument(!username.isEmpty());
// the connection
Connection connection = null;
String apiToReturn = null;
try{
connection = getConnection();
String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, username);
preparedStatement.setString(2, state);
LOG.debug("The query is: "+preparedStatement.toString());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
apiToReturn = rs.getString("apikey");
LOG.debug("Api key "+apiToReturn.substring(0,10)+" MASKED-TOKEN retrieved for user " + username);
break;
}
return apiToReturn;
}catch(Exception e){
LOG.error("Unable to retrieve key for user " + username, e);
}finally{
closeConnection(connection);
}
return null;
}
/**
* Tries to close a connection.
*
* @param connection the connection
*/
private void closeConnection(Connection connection){
if(connection != null){
try{
connection.close();
LOG.trace("CONNECTION CLOSED");
}catch(Exception e){
LOG.error("Unable to close this connection ", e);
}
}
}
}