2016-06-07 16:00:05 +02:00
package org.gcube.datacatalogue.ckanutillibrary ;
import java.sql.Connection ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
2016-06-17 22:17:42 +02:00
import java.sql.SQLException ;
2016-06-07 16:00:05 +02:00
import java.util.ArrayList ;
import java.util.HashMap ;
2016-06-14 12:31:19 +02:00
import java.util.Iterator ;
2016-06-07 16:00:05 +02:00
import java.util.List ;
import java.util.Map ;
2016-06-14 12:31:19 +02:00
import java.util.Map.Entry ;
import net.htmlparser.jericho.Renderer ;
import net.htmlparser.jericho.Segment ;
import net.htmlparser.jericho.Source ;
2016-06-07 16:00:05 +02:00
2016-06-17 22:17:42 +02:00
import org.apache.commons.dbcp2.BasicDataSource ;
2016-06-07 16:00:05 +02:00
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper ;
2016-06-14 12:31:19 +02:00
import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean ;
2016-06-14 17:05:24 +02:00
import org.gcube.datacatalogue.ckanutillibrary.models.RolesIntoOrganization ;
import org.gcube.datacatalogue.ckanutillibrary.models.State ;
2016-06-16 18:09:26 +02:00
import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods ;
2016-06-07 16:00:05 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2016-06-14 12:31:19 +02:00
import eu.trentorise.opendata.jackan.CheckedCkanClient ;
2016-06-07 16:00:05 +02:00
import eu.trentorise.opendata.jackan.CkanClient ;
2016-06-10 16:26:01 +02:00
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse ;
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpStatus ;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost ;
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity ;
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient ;
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder ;
2016-06-14 12:31:19 +02:00
import eu.trentorise.opendata.jackan.model.CkanDataset ;
2016-06-07 16:00:05 +02:00
import eu.trentorise.opendata.jackan.model.CkanLicense ;
import eu.trentorise.opendata.jackan.model.CkanOrganization ;
2016-06-14 12:31:19 +02:00
import eu.trentorise.opendata.jackan.model.CkanPair ;
import eu.trentorise.opendata.jackan.model.CkanResource ;
import eu.trentorise.opendata.jackan.model.CkanTag ;
2016-06-14 17:05:24 +02:00
import eu.trentorise.opendata.jackan.model.CkanUser ;
2016-06-07 16:00:05 +02:00
/ * *
* This is the Ckan Utils implementation class .
2016-06-14 12:31:19 +02:00
* @author Costantino Perciante at ISTI - CNR ( costantino . perciante @isti.cnr.it )
2016-06-07 16:00:05 +02:00
* /
public class CKanUtilsImpl implements CKanUtilsInterface {
private static final Logger logger = LoggerFactory . getLogger ( CKanUtilsImpl . class ) ;
private String CKAN_CATALOGUE_URL ;
private String CKAN_DB_NAME ;
private String CKAN_DB_USER ;
private String CKAN_DB_PASSWORD ;
2016-06-10 14:15:38 +02:00
private String CKAN_DB_URL ;
2016-06-07 16:00:05 +02:00
private Integer CKAN_DB_PORT ;
2016-06-16 18:09:26 +02:00
private String CKAN_TOKEN_SYS ;
2016-06-07 16:00:05 +02:00
2016-06-17 22:17:42 +02:00
// use connections pool (multiple threads can use this CKanUtilsImpl instance)
private BasicDataSource ds ;
2016-06-07 16:00:05 +02:00
2016-06-17 22:17:42 +02:00
/ * *
* The ckan catalogue url and database will be discovered in this scope
* @param scope
* @throws Exception if unable to find datacatalogue info
* /
2016-06-07 16:00:05 +02:00
public CKanUtilsImpl ( String scope ) throws Exception {
2016-06-14 12:31:19 +02:00
2016-06-16 18:09:26 +02:00
CKanRunningCluster runningInstance = new CKanRunningCluster ( scope ) ;
2016-06-17 22:17:42 +02:00
// save information
2016-06-16 18:09:26 +02:00
CKAN_DB_URL = runningInstance . getDatabaseHosts ( ) . get ( 0 ) ;
CKAN_DB_NAME = runningInstance . getDataBaseName ( ) ;
CKAN_DB_USER = runningInstance . getDataBaseUser ( ) ;
CKAN_DB_PASSWORD = runningInstance . getDataBasePassword ( ) ;
logger . debug ( " Plain password first 3 chars are " + CKAN_DB_PASSWORD . substring ( 0 , 3 ) ) ;
CKAN_TOKEN_SYS = runningInstance . getSysAdminToken ( ) ;
logger . debug ( " Plain sys admin token first 3 chars are " + CKAN_TOKEN_SYS . substring ( 0 , 3 ) ) ;
CKAN_DB_PORT = runningInstance . getDatabasePorts ( ) . get ( 0 ) ;
CKAN_CATALOGUE_URL = runningInstance . getDataCatalogueUrl ( ) . get ( 0 ) ;
2016-06-17 22:17:42 +02:00
// create connection pool
String url = " jdbc:postgresql:// " + CKAN_DB_URL + " : " + CKAN_DB_PORT + " / " + CKAN_DB_NAME ;
ds = new BasicDataSource ( ) ;
ds . setDriverClassName ( " org.postgresql.Driver " ) ;
ds . setUsername ( CKAN_DB_USER ) ;
ds . setPassword ( CKAN_DB_PASSWORD ) ;
ds . setUrl ( url ) ;
2016-06-16 18:09:26 +02:00
2016-06-17 22:17:42 +02:00
}
/ * *
* Retrieve connection from the pool
* @return
* @throws SQLException
* /
private Connection getConnection ( ) throws SQLException {
return ds . getConnection ( ) ;
2016-06-07 16:00:05 +02:00
}
@Override
2016-06-16 18:09:26 +02:00
public String getApiKeyFromUsername ( String username ) {
2016-06-14 17:05:24 +02:00
2016-06-17 22:17:42 +02:00
logger . debug ( " Request api key for user = " + username ) ;
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-14 17:05:24 +02:00
2016-06-07 16:00:05 +02:00
String apiToReturn = null ;
try {
2016-06-14 17:05:24 +02:00
String query = " SELECT \" apikey \" FROM \" user \" WHERE \" name \" =? and \" state \" =?; " ;
2016-06-17 22:17:42 +02:00
PreparedStatement preparedStatement = getConnection ( ) . prepareStatement ( query ) ;
2016-06-14 12:31:19 +02:00
preparedStatement . setString ( 1 , ckanUsername ) ;
2016-06-16 18:09:26 +02:00
preparedStatement . setString ( 2 , State . ACTIVE . toString ( ) . toLowerCase ( ) ) ;
2016-06-07 16:00:05 +02:00
ResultSet rs = preparedStatement . executeQuery ( ) ;
while ( rs . next ( ) ) {
apiToReturn = rs . getString ( " apikey " ) ;
break ;
}
2016-06-16 18:09:26 +02:00
logger . debug ( " Api key retrieved for user " + ckanUsername ) ;
2016-06-07 16:00:05 +02:00
} catch ( Exception e ) {
2016-06-14 12:31:19 +02:00
logger . error ( " Unable to retrieve key for user " + ckanUsername , e ) ;
2016-06-07 16:00:05 +02:00
}
return apiToReturn ;
}
@Override
public CKanUserWrapper getUserFromApiKey ( String apiKey ) {
logger . debug ( " Request user whose api key is = " + apiKey ) ;
CKanUserWrapper user = new CKanUserWrapper ( ) ;
try {
2016-06-14 17:05:24 +02:00
String query = " SELECT * FROM \" user \" WHERE \" apikey \" =? and \" state \" =?; " ;
2016-06-17 22:17:42 +02:00
PreparedStatement preparedStatement = getConnection ( ) . prepareStatement ( query ) ;
2016-06-07 16:00:05 +02:00
preparedStatement . setString ( 1 , apiKey ) ;
2016-06-16 18:09:26 +02:00
preparedStatement . setString ( 2 , State . ACTIVE . toString ( ) . toLowerCase ( ) ) ;
2016-06-14 17:05:24 +02:00
2016-06-07 16:00:05 +02:00
ResultSet rs = preparedStatement . executeQuery ( ) ;
while ( rs . next ( ) ) {
user . setId ( rs . getString ( " id " ) ) ;
user . setName ( rs . getString ( " name " ) ) ;
user . setApiKey ( apiKey ) ;
user . setCreationTimestamp ( rs . getTimestamp ( " created " ) . getTime ( ) ) ;
user . setAbout ( rs . getString ( " about " ) ) ;
user . setOpenId ( rs . getString ( " openid " ) ) ;
user . setFullName ( rs . getString ( " fullname " ) ) ;
user . setEmail ( rs . getString ( " email " ) ) ;
user . setAdmin ( rs . getBoolean ( " sysadmin " ) ) ;
2016-06-16 18:09:26 +02:00
logger . debug ( " User retrieved " ) ;
2016-06-07 16:00:05 +02:00
break ;
}
} catch ( Exception e ) {
2016-06-13 14:18:37 +02:00
logger . error ( " Unable to retrieve user with api key " + apiKey , e ) ;
2016-06-07 16:00:05 +02:00
}
return user ;
}
@Override
public List < CkanOrganization > getOrganizationsByUser ( String username ) {
logger . debug ( " Requested organizations for user " + username ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
String userId = getUserIdByUsername ( ckanUsername ) ;
2016-06-07 16:00:05 +02:00
// list to return
List < CkanOrganization > toReturn = new ArrayList < CkanOrganization > ( ) ;
// get the CkanClient to retrieve the organization from the id
2016-06-13 14:45:24 +02:00
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
2016-06-07 16:00:05 +02:00
try {
2016-06-17 22:17:42 +02:00
List < String > organizationIds = getOrganizationsIds ( ) ;
2016-06-07 16:00:05 +02:00
// for each org id, check if the user is included
for ( String orgId : organizationIds ) {
2016-06-14 17:05:24 +02:00
String query = " SELECT * FROM \" member \" WHERE \" table_id \" =? and \" group_id \" =? and \" table_name \" =? and \" state \" =?; " ;
2016-06-17 22:17:42 +02:00
PreparedStatement preparedStatement = getConnection ( ) . prepareStatement ( query ) ;
2016-06-07 16:00:05 +02:00
preparedStatement . setString ( 1 , userId ) ;
preparedStatement . setString ( 2 , orgId ) ;
preparedStatement . setString ( 3 , " user " ) ;
2016-06-16 18:09:26 +02:00
preparedStatement . setString ( 4 , State . ACTIVE . toString ( ) . toLowerCase ( ) ) ;
2016-06-07 16:00:05 +02:00
ResultSet rs = preparedStatement . executeQuery ( ) ;
while ( rs . next ( ) ) {
// the role within the organization doesn't matter
2016-06-14 12:31:19 +02:00
logger . debug ( " User " + ckanUsername + " belongs to organization with id " + orgId ) ;
2016-06-07 16:00:05 +02:00
toReturn . add ( client . getOrganization ( orgId ) ) ;
}
}
} catch ( Exception e ) {
logger . error ( " Unable to get user's organizations " , e ) ;
}
return toReturn ;
}
@Override
2016-06-14 17:05:24 +02:00
public Map < String , List < RolesIntoOrganization > > getGroupsAndRolesByUser (
String username , List < RolesIntoOrganization > rolesToMatch ) {
2016-06-07 16:00:05 +02:00
2016-06-16 18:09:26 +02:00
logger . debug ( " Requested roles the user " + username + " has into his organizations " ) ;
2016-06-07 16:00:05 +02:00
logger . debug ( " Roles to check are " + rolesToMatch ) ;
2016-06-14 17:05:24 +02:00
Map < String , List < RolesIntoOrganization > > toReturn = new HashMap < String , List < RolesIntoOrganization > > ( ) ;
2016-06-07 16:00:05 +02:00
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-17 22:17:42 +02:00
// retrieve the user and if it is a sys_admin, for every organizations that will be created in the map add also
2016-06-14 17:05:24 +02:00
// the sys_admin role
boolean isSysAdmin = false ;
if ( rolesToMatch . contains ( RolesIntoOrganization . SYSADMIN ) ) {
2016-06-17 22:17:42 +02:00
// get its key
String apiKey = getApiKeyFromUsername ( ckanUsername ) ;
2016-06-16 18:09:26 +02:00
isSysAdmin = isSysAdmin ( ckanUsername , apiKey ) ;
2016-06-14 17:05:24 +02:00
}
2016-06-07 16:00:05 +02:00
try {
// get id from the user
2016-06-14 12:31:19 +02:00
String userId = getUserIdByUsername ( ckanUsername ) ;
2016-06-07 16:00:05 +02:00
2016-06-17 22:17:42 +02:00
// get the id of all the organizations
List < String > organizationIds = getOrganizationsIds ( ) ;
2016-06-17 22:42:31 +02:00
// we need to get orgs names
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
2016-06-07 16:00:05 +02:00
2016-06-17 22:17:42 +02:00
for ( String orgId : organizationIds ) {
2016-06-07 16:00:05 +02:00
// go to the member table, that says which role has this user into the org
2016-06-14 17:05:24 +02:00
String query = " SELECT * FROM \" member \" WHERE \" table_id \" =? and \" group_id \" =? and \" table_name \" =? and \" state \" =?; " ;
2016-06-17 22:17:42 +02:00
PreparedStatement preparedStatement = getConnection ( ) . prepareStatement ( query ) ;
2016-06-07 16:00:05 +02:00
preparedStatement . setString ( 1 , userId ) ;
preparedStatement . setString ( 2 , orgId ) ;
preparedStatement . setString ( 3 , " user " ) ;
2016-06-16 18:09:26 +02:00
preparedStatement . setString ( 4 , State . ACTIVE . toString ( ) . toLowerCase ( ) ) ;
2016-06-07 16:00:05 +02:00
ResultSet rs = preparedStatement . executeQuery ( ) ;
// prepare the data to put into the hashmap
2016-06-14 17:05:24 +02:00
List < RolesIntoOrganization > rolesIntoOrg = new ArrayList < RolesIntoOrganization > ( ) ;
if ( isSysAdmin )
rolesIntoOrg . add ( RolesIntoOrganization . SYSADMIN ) ;
2016-06-07 16:00:05 +02:00
while ( rs . next ( ) ) {
// check
String role = rs . getString ( " capacity " ) ;
2016-06-14 17:05:24 +02:00
if ( rolesToMatch . contains ( RolesIntoOrganization . valueOf ( role ) ) ) {
rolesIntoOrg . add ( RolesIntoOrganization . valueOf ( role ) ) ;
2016-06-17 22:17:42 +02:00
logger . debug ( " User " + ckanUsername + " has role " + role + " into organization with id " + orgId ) ;
2016-06-07 16:00:05 +02:00
}
}
2016-06-17 22:42:31 +02:00
if ( ! rolesIntoOrg . isEmpty ( ) ) {
String orgName = client . getOrganization ( orgId ) . getName ( ) ;
toReturn . put ( orgName , rolesIntoOrg ) ;
}
2016-06-07 16:00:05 +02:00
}
} catch ( Exception e ) {
logger . error ( " Unable to analyze user's roles " , e ) ;
}
return toReturn ;
}
/ * *
* Returns the user id given his username
* @param username
* @return the id on success , null otherwise
* /
private String getUserIdByUsername ( String username ) {
logger . debug ( " Request user id whose username is = " + username ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-17 22:17:42 +02:00
String userId = null ;
2016-06-07 16:00:05 +02:00
try {
2016-06-17 22:17:42 +02:00
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
client . getUser ( ckanUsername ) . getId ( ) ;
2016-06-16 18:09:26 +02:00
logger . debug ( " User id retrieved for " + ckanUsername + " " + userId ) ;
2016-06-07 16:00:05 +02:00
} catch ( Exception e ) {
2016-06-14 12:31:19 +02:00
logger . error ( " Unable to retrieve user with name " + ckanUsername , e ) ;
2016-06-07 16:00:05 +02:00
}
return userId ;
}
2016-06-18 10:12:47 +02:00
@Override
public List < String > getOrganizationsIds ( ) {
2016-06-16 18:09:26 +02:00
2016-06-07 16:00:05 +02:00
List < String > toReturn = new ArrayList < String > ( ) ;
2016-06-16 18:09:26 +02:00
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
List < CkanOrganization > orgs = client . getOrganizationList ( ) ;
2016-06-07 16:00:05 +02:00
2016-06-16 18:09:26 +02:00
for ( CkanOrganization ckanOrganization : orgs ) {
logger . debug ( " Retrieved org " + ckanOrganization . getName ( ) ) ;
toReturn . add ( ckanOrganization . getId ( ) ) ;
2016-06-07 16:00:05 +02:00
}
2016-06-16 18:09:26 +02:00
return toReturn ;
2016-06-10 14:15:38 +02:00
}
2016-06-18 10:12:47 +02:00
@Override
public List < String > getOrganizationsNames ( ) {
List < String > toReturn = new ArrayList < String > ( ) ;
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
List < CkanOrganization > orgs = client . getOrganizationList ( ) ;
for ( CkanOrganization ckanOrganization : orgs ) {
logger . debug ( " Retrieved org " + ckanOrganization . getName ( ) ) ;
toReturn . add ( ckanOrganization . getName ( ) ) ;
}
return toReturn ;
}
2016-06-10 16:26:01 +02:00
2016-06-07 16:00:05 +02:00
@Override
public String getCatalogueUrl ( ) {
2016-06-10 14:15:38 +02:00
return CKAN_CATALOGUE_URL ;
2016-06-07 16:00:05 +02:00
}
@Override
public List < String > getOrganizationsNamesByUser ( String username ) {
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
logger . debug ( " Requested organizations for user " + username ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
List < CkanOrganization > orgs = getOrganizationsByUser ( ckanUsername ) ;
2016-06-17 22:17:42 +02:00
2016-06-07 16:00:05 +02:00
List < String > orgsName = new ArrayList < String > ( ) ;
for ( CkanOrganization ckanOrganization : orgs ) {
orgsName . add ( ckanOrganization . getName ( ) ) ;
logger . debug ( " Organization name is " + ckanOrganization . getName ( ) ) ;
}
return orgsName ;
2016-06-08 18:31:25 +02:00
2016-06-07 16:00:05 +02:00
}
@Override
public String findLicenseIdByLicense ( String chosenLicense ) {
logger . debug ( " Requested license id " ) ;
2016-06-16 18:09:26 +02:00
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
2016-06-07 16:00:05 +02:00
//retrieve the list of available licenses
List < CkanLicense > licenses = client . getLicenseList ( ) ;
for ( CkanLicense ckanLicense : licenses ) {
if ( ckanLicense . getTitle ( ) . equals ( chosenLicense ) )
return ckanLicense . getId ( ) ;
}
return null ;
}
@Override
public List < String > getLicenseTitles ( ) {
2016-06-14 12:31:19 +02:00
logger . debug ( " Request for CKAN licenses " ) ;
2016-06-07 16:00:05 +02:00
// get the url and the api key of the user
List < String > result = new ArrayList < String > ( ) ;
2016-06-16 18:09:26 +02:00
CkanClient client = new CkanClient ( CKAN_CATALOGUE_URL ) ;
2016-06-07 16:00:05 +02:00
//retrieve the list of available licenses
List < CkanLicense > licenses = client . getLicenseList ( ) ;
for ( CkanLicense ckanLicense : licenses ) {
result . add ( ckanLicense . getTitle ( ) ) ;
logger . debug ( " License is " + ckanLicense . getTitle ( ) + " and id " + ckanLicense . getId ( ) ) ;
}
2016-06-08 18:31:25 +02:00
2016-06-07 16:00:05 +02:00
return result ;
}
2016-06-10 14:15:38 +02:00
2016-06-10 16:26:01 +02:00
@Override
public boolean setDatasetPrivate ( boolean priv , String organizationId ,
2016-06-16 18:09:26 +02:00
String datasetId , String apiKey ) {
2016-06-10 16:26:01 +02:00
String pathSetPrivate = " /api/3/action/bulk_update_private " ;
String pathSetPublic = " /api/3/action/bulk_update_public " ;
2016-06-14 17:05:24 +02:00
2016-06-16 18:09:26 +02:00
if ( apiKey = = null | | apiKey . isEmpty ( ) ) {
logger . error ( " The apiKey parameter is mandatory " ) ;
2016-06-10 16:26:01 +02:00
return false ;
}
// Request parameters to be replaced
String parameter = " { "
+ " \" org_id \" : \" ORGANIZATION_ID \" , "
+ " \" datasets \" :[ \" DATASET_ID \" ] "
+ " } " ;
if ( organizationId ! = null & & ! organizationId . isEmpty ( ) & & datasetId ! = null & & ! datasetId . isEmpty ( ) ) {
// replace with right data
parameter = parameter . replace ( " ORGANIZATION_ID " , organizationId ) ;
parameter = parameter . replace ( " DATASET_ID " , datasetId ) ;
CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ;
if ( priv ) {
try {
HttpPost request = new HttpPost ( CKAN_CATALOGUE_URL + pathSetPrivate ) ;
2016-06-16 18:09:26 +02:00
request . addHeader ( " Authorization " , apiKey ) ;
2016-06-10 16:26:01 +02:00
StringEntity params = new StringEntity ( parameter ) ;
request . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( request ) ;
logger . debug ( " [PRIVATE]Response code is " + response . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
if ( response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK )
return true ;
} catch ( Exception ex ) {
2016-06-13 14:18:37 +02:00
logger . error ( " Error while trying to set private the dataset " , ex ) ;
2016-06-10 16:26:01 +02:00
}
} else
{
try {
HttpPost request = new HttpPost ( CKAN_CATALOGUE_URL + pathSetPublic ) ;
StringEntity params = new StringEntity ( parameter ) ;
2016-06-16 18:09:26 +02:00
request . addHeader ( " Authorization " , apiKey ) ;
2016-06-10 16:26:01 +02:00
request . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( request ) ;
logger . debug ( " [PUBLIC]Response code is " + response . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
2016-06-13 12:07:41 +02:00
2016-06-10 16:26:01 +02:00
if ( response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK )
return true ;
2016-06-13 12:07:41 +02:00
2016-06-10 16:26:01 +02:00
} catch ( Exception ex ) {
2016-06-13 14:18:37 +02:00
logger . error ( " Error while trying to set public the dataset " , ex ) ;
2016-06-10 16:26:01 +02:00
}
}
}
return false ;
}
2016-06-14 12:31:19 +02:00
@Override
2016-06-16 18:09:26 +02:00
public String addResourceToDataset ( ResourceBean resourceBean , String apiKey ) {
2016-06-14 12:31:19 +02:00
logger . debug ( " Request to add a resource described by this bean " + resourceBean ) ;
try {
2016-06-16 18:09:26 +02:00
if ( UtilMethods . resourceExists ( resourceBean . getUrl ( ) ) ) {
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
// in order to avoid errors, the username is always converted
2016-06-16 18:09:26 +02:00
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( resourceBean . getOwner ( ) ) ;
2016-06-14 17:05:24 +02:00
2016-06-16 18:09:26 +02:00
CkanResource resource = new CkanResource ( CKAN_CATALOGUE_URL , resourceBean . getDatasetId ( ) ) ;
2016-06-14 12:31:19 +02:00
resource . setName ( resourceBean . getName ( ) ) ;
// escape description
Source description = new Source ( resourceBean . getDescription ( ) ) ;
Segment htmlSeg = new Segment ( description , 0 , description . length ( ) ) ;
Renderer htmlRend = new Renderer ( htmlSeg ) ;
resource . setDescription ( htmlRend . toString ( ) ) ;
resource . setUrl ( resourceBean . getUrl ( ) ) ;
resource . setOwner ( ckanUsername ) ;
// Checked client
2016-06-16 18:09:26 +02:00
CheckedCkanClient client = new CheckedCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
2016-06-14 12:31:19 +02:00
CkanResource createdRes = client . createResource ( resource ) ;
if ( createdRes ! = null ) {
logger . debug ( " Resource " + createdRes . getName ( ) + " is now available " ) ;
return createdRes . getId ( ) ;
}
} else
logger . error ( " There is no resource at this url " + resourceBean . getUrl ( ) ) ;
} catch ( Exception e ) {
logger . error ( " Unable to create the resource described by the bean " + resourceBean , e ) ;
}
return null ;
}
@Override
2016-06-16 18:09:26 +02:00
public boolean deleteResourceFromDataset ( String resourceId , String apiKey ) {
2016-06-14 17:05:24 +02:00
2016-06-16 18:09:26 +02:00
logger . error ( " Request to delete a resource with id " + resourceId + " coming by user with key " + apiKey ) ;
2016-06-14 12:31:19 +02:00
try {
2016-06-16 18:09:26 +02:00
CheckedCkanClient client = new CheckedCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
2016-06-14 12:31:19 +02:00
client . deleteResource ( resourceId ) ;
return true ;
} catch ( Exception e ) {
logger . error ( " Unable to delete resource whose id is " + resourceId , e ) ;
}
return false ;
}
@Override
2016-06-16 18:09:26 +02:00
public String createCKanDataset ( String apiKey , String withId ,
2016-06-14 12:31:19 +02:00
String title , String organizationNameOrId , String author ,
String authorMail , String maintainer , String maintainerMail ,
long version , String description , String licenseId ,
List < String > tags , Map < String , String > customFields ,
List < ResourceBean > resources , boolean setPublic ) {
logger . debug ( " Request for dataset creation " ) ;
2016-06-14 17:05:24 +02:00
2016-06-16 18:09:26 +02:00
CheckedCkanClient client = new CheckedCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
2016-06-14 12:31:19 +02:00
2016-06-16 18:09:26 +02:00
// get client from apiKey
String ckanUsername = getUserFromApiKey ( apiKey ) . getName ( ) ;
2016-06-14 12:31:19 +02:00
// create the base dataset and fill it
CkanDataset dataset = new CkanDataset ( ) ;
// set values
dataset . setId ( withId ) ;
// get the name from the title
2016-06-16 18:09:26 +02:00
dataset . setName ( UtilMethods . nameFromTitle ( title ) ) ;
2016-06-14 12:31:19 +02:00
dataset . setTitle ( title ) ;
CkanOrganization orgOwner = client . getOrganization ( organizationNameOrId ) ;
dataset . setOwnerOrg ( orgOwner . getId ( ) ) ;
dataset . setAuthor ( author ) ;
dataset . setAuthorEmail ( authorMail ) ;
dataset . setMaintainer ( maintainer ) ;
dataset . setMaintainerEmail ( maintainerMail ) ;
dataset . setVersion ( String . valueOf ( version ) ) ;
// description must be escaped
Source descriptionEscaped = new Source ( description ) ;
Segment htmlSeg = new Segment ( descriptionEscaped , 0 , descriptionEscaped . length ( ) ) ;
Renderer htmlRend = new Renderer ( htmlSeg ) ;
dataset . setNotes ( htmlRend . toString ( ) ) ;
logger . debug ( " Description (escaped is ) " + htmlRend . toString ( ) ) ;
dataset . setLicenseId ( licenseId ) ;
// set the tags, if any
if ( tags ! = null & & ! tags . isEmpty ( ) ) {
// convert to ckan tags
List < CkanTag > ckanTags = new ArrayList < CkanTag > ( tags . size ( ) ) ;
for ( String stringTag : tags ) {
ckanTags . add ( new CkanTag ( stringTag ) ) ;
}
dataset . setTags ( ckanTags ) ;
}
// set the custom fields, if any
if ( customFields ! = null & & ! customFields . isEmpty ( ) ) {
// iterate and create
Iterator < Entry < String , String > > iterator = customFields . entrySet ( ) . iterator ( ) ;
List < CkanPair > extras = new ArrayList < CkanPair > ( customFields . entrySet ( ) . size ( ) ) ;
while ( iterator . hasNext ( ) ) {
Map . Entry < String , String > entry = ( Map . Entry < String , String > ) iterator . next ( ) ;
extras . add ( new CkanPair ( entry . getKey ( ) , entry . getValue ( ) ) ) ;
}
dataset . setExtras ( extras ) ;
}
// check if we need to add the resources
if ( resources ! = null & & ! resources . isEmpty ( ) ) {
logger . debug ( " We need to add resources to the dataset " ) ;
try {
List < CkanResource > resourcesCkan = new ArrayList < CkanResource > ( ) ;
for ( ResourceBean resource : resources ) {
CkanResource newResource = new CkanResource ( ) ;
newResource . setDescription ( resource . getDescription ( ) ) ;
newResource . setId ( resource . getId ( ) ) ;
newResource . setUrl ( resource . getUrl ( ) ) ;
newResource . setName ( resource . getName ( ) ) ;
newResource . setMimetype ( resource . getMimeType ( ) ) ;
newResource . setOwner ( ckanUsername ) ;
resourcesCkan . add ( newResource ) ;
}
// add to the dataset
dataset . setResources ( resourcesCkan ) ;
} catch ( Exception e ) {
logger . error ( " Unable to add those resources to the dataset " , e ) ;
}
}
// try to create
CkanDataset res = null ;
try {
res = client . createDataset ( dataset ) ;
if ( res ! = null ) {
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
logger . debug ( " Dataset with name " + res . getName ( ) + " has been created. Setting visibility " ) ;
// set visibility
setDatasetPrivate (
! setPublic , // swap to private
res . getOrganization ( ) . getId ( ) ,
res . getId ( ) ,
ckanUsername ) ;
return res . getId ( ) ;
}
} catch ( Exception e ) {
// try to update
2016-06-16 18:09:26 +02:00
logger . error ( " Error while creating the dataset. " , e ) ;
2016-06-14 12:31:19 +02:00
}
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
return null ;
}
@Override
2016-06-16 18:09:26 +02:00
public String getUrlFromDatasetIdOrName ( String apiKey , String datasetIdOrName ) {
2016-06-14 12:31:19 +02:00
logger . debug ( " Request coming for dataset url of dataset with name/id " + datasetIdOrName ) ;
2016-06-14 17:05:24 +02:00
2016-06-14 12:31:19 +02:00
// the url of the dataset looks like "getCatalogueUrl() + /dataset/ + dataset name"
try {
2016-06-16 18:09:26 +02:00
CheckedCkanClient client = new CheckedCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
2016-06-14 12:31:19 +02:00
CkanDataset dataset = client . getDataset ( datasetIdOrName ) ;
if ( dataset ! = null ) {
2016-06-16 18:09:26 +02:00
return CKAN_CATALOGUE_URL + " /dataset/ " + dataset . getName ( ) ;
2016-06-14 12:31:19 +02:00
}
} catch ( Exception e ) {
logger . error ( " Error while retrieving dataset with id/name= " + datasetIdOrName , e ) ;
}
return null ;
}
2016-06-14 17:05:24 +02:00
@Override
2016-06-18 10:05:10 +02:00
public boolean checkRole ( String username , String organizationName ,
2016-06-14 17:05:24 +02:00
RolesIntoOrganization correspondentRoleToCheck ) {
2016-06-16 18:09:26 +02:00
logger . debug ( " Request for checking if " + username + " into " + organizationName + " has role " + correspondentRoleToCheck ) ;
if ( correspondentRoleToCheck . equals ( RolesIntoOrganization . SYSADMIN ) ) {
2016-06-17 22:17:42 +02:00
2016-06-16 18:09:26 +02:00
logger . debug ( " SYSADMIN role cannot be created programmatically... The user role will be turned into admin " ) ;
correspondentRoleToCheck = RolesIntoOrganization . ADMIN ;
}
// convert ckan username
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
// we need to use the apis to make this
String path = " /api/3/action/organization_member_create " ;
// Request parameters to be replaced
String parameter = " { "
+ " \" id \" : \" ORGANIZATION_ID_NAME \" , "
+ " \" username \" : \" USERNAME_ID_NAME \" , "
+ " \" role \" : \" ROLE \" "
+ " } " ;
// replace those values
parameter = parameter . replace ( " ORGANIZATION_ID_NAME " , organizationName . toLowerCase ( ) ) ;
parameter = parameter . replace ( " USERNAME_ID_NAME " , ckanUsername ) ;
parameter = parameter . replace ( " ROLE " , correspondentRoleToCheck . toString ( ) . toLowerCase ( ) ) ;
logger . debug ( " API request for organization membership is going to be " + parameter ) ;
CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ;
try {
HttpPost request = new HttpPost ( CKAN_CATALOGUE_URL + path ) ;
request . addHeader ( " Authorization " , CKAN_TOKEN_SYS ) ; // sys token
StringEntity params = new StringEntity ( parameter ) ;
request . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( request ) ;
logger . debug ( " Response code is " + response . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
2016-06-18 10:05:10 +02:00
return ( response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK ) ;
2016-06-16 18:09:26 +02:00
} catch ( Exception ex ) {
logger . error ( " Error while trying to change the role for this user " , ex ) ;
}
2016-06-18 10:05:10 +02:00
return false ;
2016-06-14 17:05:24 +02:00
}
@Override
2016-06-16 18:09:26 +02:00
public boolean isSysAdmin ( String username , String apiKey ) {
2016-06-18 10:05:10 +02:00
// in order to avoid errors, the username is always converted
String ckanUsername = UtilMethods . fromUsernameToCKanUsername ( username ) ;
2016-06-16 18:09:26 +02:00
try {
CheckedCkanClient checkedClient = new CheckedCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
2016-06-18 10:05:10 +02:00
CkanUser user = checkedClient . getUser ( ckanUsername ) ;
2016-06-16 18:09:26 +02:00
return user . isSysadmin ( ) ;
} catch ( Exception e ) {
logger . error ( " Failed to check if the user " + username + " has role sysadmin " , e ) ;
}
return false ;
2016-06-14 17:05:24 +02:00
}
2016-06-14 12:31:19 +02:00
@Override
protected void finalize ( ) throws Throwable {
2016-06-18 10:05:10 +02:00
logger . debug ( " Closing connection pool on finalize() " ) ;
2016-06-17 22:17:42 +02:00
ds . close ( ) ;
2016-06-14 12:31:19 +02:00
}
2016-06-07 16:00:05 +02:00
}