2020-06-01 16:00:23 +02:00
package org.gcube.datacatalogue.ckanutillibrary.server ;
import static com.google.common.base.Preconditions.checkArgument ;
import static com.google.common.base.Preconditions.checkNotNull ;
import java.net.URLEncoder ;
import java.util.ArrayList ;
2021-02-11 16:09:17 +01:00
import java.util.Arrays ;
2020-06-01 16:00:23 +02:00
import java.util.HashMap ;
2021-02-11 16:09:17 +01:00
import java.util.HashSet ;
import java.util.Iterator ;
2020-06-01 16:00:23 +02:00
import java.util.List ;
2021-02-11 16:09:17 +01:00
import java.util.ListIterator ;
2020-06-01 16:00:23 +02:00
import java.util.Map ;
2021-02-11 16:09:17 +01:00
import java.util.Set ;
2020-06-01 16:00:23 +02:00
import java.util.concurrent.ConcurrentHashMap ;
2021-02-09 16:32:25 +01:00
import org.apache.http.HttpResponse ;
import org.apache.http.HttpStatus ;
2021-02-11 16:09:17 +01:00
import org.apache.http.client.methods.HttpGet ;
2021-02-09 16:32:25 +01:00
import org.apache.http.client.methods.HttpPost ;
import org.apache.http.entity.ContentType ;
import org.apache.http.entity.StringEntity ;
import org.apache.http.impl.client.CloseableHttpClient ;
import org.apache.http.impl.client.HttpClientBuilder ;
import org.apache.http.util.EntityUtils ;
2020-06-01 16:00:23 +02:00
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
2021-02-11 11:03:22 +01:00
import org.gcube.common.scope.api.ScopeProvider ;
2020-06-01 16:00:23 +02:00
import org.gcube.common.scope.impl.ScopeBean ;
import org.gcube.common.scope.impl.ScopeBean.Type ;
import org.gcube.datacatalogue.ckanutillibrary.ckan.ExtendCkanClient ;
2020-06-03 14:39:41 +02:00
import org.gcube.datacatalogue.ckanutillibrary.ckan.MarshUnmarshCkanObject ;
2020-09-02 17:40:12 +02:00
import org.gcube.datacatalogue.ckanutillibrary.ckan.MarshUnmarshCkanObject.METHOD ;
2020-06-01 16:00:23 +02:00
import org.gcube.datacatalogue.ckanutillibrary.db.DBCaller ;
import org.gcube.datacatalogue.ckanutillibrary.gcat.GCatCaller ;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET ;
2021-02-08 17:44:09 +01:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CKANConveter ;
2020-06-01 16:00:23 +02:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods ;
2021-02-11 11:03:22 +01:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.GCubeUtils ;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.GCubeUtils.GCUBE_SCOPE_LEVEL ;
2020-06-01 16:00:23 +02:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.url.EntityContext ;
2020-06-03 16:29:47 +02:00
import org.gcube.datacatalogue.ckanutillibrary.shared.LandingPages ;
2020-06-01 16:00:23 +02:00
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean ;
import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg ;
import org.gcube.datacatalogue.ckanutillibrary.shared.State ;
2021-02-09 16:32:25 +01:00
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanLicense ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResource ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanUser ;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.JackanException ;
2021-02-11 16:09:17 +01:00
import org.json.simple.JSONArray ;
2020-06-01 16:00:23 +02:00
import org.json.simple.JSONObject ;
2021-02-11 16:09:17 +01:00
import org.json.simple.parser.JSONParser ;
2020-06-01 16:00:23 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2021-02-09 16:32:25 +01:00
2020-06-03 16:29:47 +02:00
/ * *
* This is the Ckan Utils implementation class .
*
* revisited by
* @author Francesco Mangiacrapa at ISTI - CNR
2020-08-28 12:31:49 +02:00
*
* @author Costantino Perciante at ISTI - CNR ( costantino . perciante @isti.cnr.it )
2020-06-03 16:29:47 +02:00
* /
2020-06-01 16:00:23 +02:00
public class DataCatalogueImpl implements DataCatalogue {
private static final Logger LOG = LoggerFactory . getLogger ( DataCatalogueImpl . class ) ;
private String CKAN_CATALOGUE_URL ;
private String CKAN_DB_NAME ;
private String CKAN_DB_USER ;
private String CKAN_DB_PASSWORD ;
private String CKAN_DB_URL ;
private Integer CKAN_DB_PORT ;
private String PORTLET_URL_FOR_SCOPE ;
private String SOLR_URL ;
private String CKAN_TOKEN_SYS ;
private String CKAN_EMAIL ;
private String URI_RESOLVER_URL ;
private boolean MANAGE_PRODUCT_BUTTON ;
private boolean SOCIAL_POST ;
private boolean ALERT_USERS_ON_POST_CREATION ;
private String CONTEXT ;
private Map < String , String > extendRoleInOrganization ;
public Map < ACCESS_LEVEL_TO_CATALOGUE_PORTLET , String > mapAccessURLToCatalogue ;
2020-06-03 14:39:41 +02:00
2020-06-01 16:00:23 +02:00
private static final String CATALOGUE_TAB_ENDING_URL = " /catalogue " ;
// gCat client
private GCatCaller gCatCaller ;
// db client
private DBCaller dbCaller ;
// ckan client
2020-06-03 14:39:41 +02:00
private ExtendCkanClient ckanCaller ;
2020-06-01 16:00:23 +02:00
// hashmap for ckan api keys
private ConcurrentHashMap < String , CKANTokenBean > apiKeysMap ;
2020-06-03 14:39:41 +02:00
//http ckan caller
2020-08-28 15:29:42 +02:00
//private DirectCkanCaller directCkanCaller; //is not needed anymore?
2020-06-01 16:00:23 +02:00
// apikey bean expires after X minutes in the above map
private static final int EXPIRE_KEY_TIME = 60 * 60 * 1000 ;
/ * *
* The ckan catalogue url and database will be discovered in this scope
* @param scope
* @throws Exception if unable to find datacatalogue info
* /
public DataCatalogueImpl ( String scope ) throws Exception {
DataCatalogueRunningCluster runningInstance = new DataCatalogueRunningCluster ( scope ) ;
// save information
CKAN_DB_URL = runningInstance . getDatabaseHosts ( ) . get ( 0 ) . trim ( ) ;
CKAN_DB_PORT = runningInstance . getDatabasePorts ( ) . get ( 0 ) ;
CKAN_DB_NAME = runningInstance . getDataBaseName ( ) . trim ( ) ;
CKAN_DB_USER = runningInstance . getDataBaseUser ( ) . trim ( ) ;
CKAN_DB_PASSWORD = runningInstance . getDataBasePassword ( ) . trim ( ) ;
2020-06-03 14:39:41 +02:00
CKAN_TOKEN_SYS = runningInstance . getSysAdminToken ( ) . trim ( ) ;
2020-06-01 16:00:23 +02:00
CKAN_EMAIL = runningInstance . getEmailCatalogue ( ) . trim ( ) ;
CKAN_CATALOGUE_URL = runningInstance . getDataCatalogueUrl ( ) . get ( 0 ) . trim ( ) ;
PORTLET_URL_FOR_SCOPE = runningInstance . getPortletUrl ( ) . trim ( ) ;
mapAccessURLToCatalogue = runningInstance . getMapAccessURLToCatalogue ( ) ;
MANAGE_PRODUCT_BUTTON = runningInstance . isManageProductEnabled ( ) ;
URI_RESOLVER_URL = runningInstance . getUrlResolver ( ) ;
SOCIAL_POST = runningInstance . isSocialPostEnabled ( ) ;
ALERT_USERS_ON_POST_CREATION = runningInstance . isAlertEnabled ( ) ;
SOLR_URL = runningInstance . getUrlSolr ( ) ;
LOG . info ( " In the scope: " + scope + " , I read the catalogue URL: " + CKAN_CATALOGUE_URL ) ;
// build the clients
gCatCaller = new GCatCaller ( CKAN_CATALOGUE_URL ) ;
dbCaller = new DBCaller ( CKAN_DB_URL , CKAN_DB_PORT , CKAN_DB_NAME , CKAN_DB_USER , CKAN_DB_PASSWORD ) ;
2020-06-03 14:39:41 +02:00
ckanCaller = new ExtendCkanClient ( CKAN_CATALOGUE_URL ) ;
2020-08-28 15:29:42 +02:00
//directCkanCaller = new DirectCkanCaller(CKAN_CATALOGUE_URL); //is not needed anymore?
2020-06-01 16:00:23 +02:00
// init map
apiKeysMap = new ConcurrentHashMap < String , CKANTokenBean > ( ) ;
// save the context
CONTEXT = scope ;
// extended roles
extendRoleInOrganization = runningInstance . getExtendRoleInOrganization ( ) ;
}
2020-08-27 14:37:19 +02:00
/ * *
* The ckan catalogue url and database will be discovered in this scope .
*
* @param scope the scope
* @param sysAuthentication if true perform the sys authentication
* @throws Exception if unable to find datacatalogue info
* /
public DataCatalogueImpl ( String scope , boolean sysAuthentication ) throws Exception {
this ( scope ) ;
if ( sysAuthentication )
ckanCaller = new ExtendCkanClient ( CKAN_CATALOGUE_URL , CKAN_TOKEN_SYS ) ;
}
2020-06-01 16:00:23 +02:00
@Override
public String getCatalogueUrl ( ) {
return CKAN_CATALOGUE_URL ;
}
@Override
public String getPortletUrl ( ) {
//PATCHED By Francesco
ScopeBean context = new ScopeBean ( CONTEXT ) ;
if ( context . is ( Type . INFRASTRUCTURE ) ) {
LOG . info ( " Working with the {} scope returning the path read from GR 'Ckan-Porltet': {} " , Type . INFRASTRUCTURE . toString ( ) , PORTLET_URL_FOR_SCOPE ) ;
return PORTLET_URL_FOR_SCOPE ;
}
String vreNameLower = context . name ( ) . toLowerCase ( ) ;
//CHECKING IF THE PORTLET URL CONTAINS THE VRE NAME INTO URL
if ( PORTLET_URL_FOR_SCOPE . toLowerCase ( ) . contains ( vreNameLower ) ) {
//THE PORLTET URL READ FROM GENERIC RESOUCE 'CkanPortlet' SHOULD BE ALREADY VALID, POITING TO CKAN PORTLET
return PORTLET_URL_FOR_SCOPE ;
} else {
//ADDING VRE getApiKeyFromUsernameNAME AND THE SUFFIX 'CATALOGUE_TAB_ENDING_URL' TO URL
String buildedUrl = PORTLET_URL_FOR_SCOPE . endsWith ( " / " ) ? PORTLET_URL_FOR_SCOPE : PORTLET_URL_FOR_SCOPE + " / " ;
String defaultSuffix = vreNameLower + CATALOGUE_TAB_ENDING_URL ;
buildedUrl + = defaultSuffix ;
LOG . warn ( " The Portlet URL read from Generic Resource 'Ckan-Porltet' does not contain the portlet suffix, so I added the default: " + defaultSuffix ) ;
return buildedUrl ;
}
}
@Override
public String findLicenseIdByLicenseTitle ( String chosenLicense ) {
LOG . debug ( " Requested license id " ) ;
// checks
checkNotNull ( chosenLicense ) ;
//retrieve the list of available licenses
List < CkanLicense > licenses = ckanCaller . getLicenseList ( ) ;
for ( CkanLicense ckanLicense : licenses ) {
if ( ckanLicense . getTitle ( ) . equals ( chosenLicense ) )
return ckanLicense . getId ( ) ;
}
return null ;
}
@Override
public List < String > getLicenseTitles ( ) {
LOG . debug ( " Request for CKAN licenses " ) ;
// get the url and the api key of the user
List < String > result = new ArrayList < String > ( ) ;
2021-02-11 11:03:22 +01:00
// retrieve the list of available licenses
2020-06-01 16:00:23 +02:00
List < CkanLicense > licenses = ckanCaller . getLicenseList ( ) ;
for ( CkanLicense ckanLicense : licenses ) {
result . add ( ckanLicense . getTitle ( ) ) ;
LOG . debug ( " License is " + ckanLicense . getTitle ( ) + " and id " + ckanLicense . getId ( ) ) ;
}
return result ;
}
@Override
public List < CkanLicense > getLicenses ( ) {
LOG . debug ( " Request for CKAN licenses (original jackan objects are going to be retrieved) " ) ;
2021-02-11 11:03:22 +01:00
// retrieve the list of available licenses
2020-06-01 16:00:23 +02:00
return ckanCaller . getLicenseList ( ) ;
}
2021-02-11 11:03:22 +01:00
/ *
* ( non - Javadoc )
*
* @see
* org . gcube . datacatalogue . ckanutillibrary . server . DataCatalogue # getDataset ( java .
* lang . String , java . lang . String )
2021-02-09 17:55:44 +01:00
* /
2020-06-01 16:00:23 +02:00
@Override
public CkanDataset getDataset ( String datasetId , String apiKey ) {
LOG . info ( " Request ckan dataset with id " + datasetId ) ;
// checks
checkNotNull ( datasetId ) ;
checkArgument ( ! datasetId . isEmpty ( ) ) ;
2021-02-11 11:03:22 +01:00
try {
if ( apiKey ! = null & & ! apiKey . isEmpty ( ) ) {
LOG . info ( " API-KEY found. Calling the " + ExtendCkanClient . class . getSimpleName ( ) ) ;
2020-06-01 16:00:23 +02:00
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
return client . getDataset ( datasetId ) ;
}
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
String authzToken = SecurityTokenProvider . instance . get ( ) ;
2021-02-11 11:03:22 +01:00
if ( authzToken ! = null & & ! authzToken . isEmpty ( ) ) {
2020-06-01 16:00:23 +02:00
LOG . info ( " gcube-token found. Calling the gCat client " ) ;
2020-06-03 14:39:41 +02:00
String jsonDataset = gCatCaller . getDatasetForName ( datasetId ) ;
2020-09-02 17:40:12 +02:00
return MarshUnmarshCkanObject . toCkanDataset ( jsonDataset , METHOD . TO_READ ) ;
2020-06-01 16:00:23 +02:00
}
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
LOG . info ( " No api-key or gcube-token found. Calling Ckan Client without API-KEY " ) ;
return ckanCaller . getDataset ( datasetId ) ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Unable to retrieve such dataset, returning null ... " , e ) ;
}
return null ;
}
@Override
public String getUnencryptedUrlFromDatasetIdOrName ( String datasetIdOrName ) {
LOG . debug ( " Request coming for getting dataset url (not encrypted) of dataset with name/id " + datasetIdOrName ) ;
// checks
checkNotNull ( datasetIdOrName ) ;
checkArgument ( ! datasetIdOrName . isEmpty ( ) ) ;
String url = null ;
2021-02-11 11:03:22 +01:00
try {
2020-06-01 16:00:23 +02:00
// get the dataset from name
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , CKAN_TOKEN_SYS ) ;
CkanDataset dataset = client . getDataset ( datasetIdOrName ) ;
String name = dataset . getName ( ) ;
2021-02-11 11:03:22 +01:00
if ( dataset ! = null ) {
2020-06-01 16:00:23 +02:00
2021-02-11 11:03:22 +01:00
if ( getUriResolverUrl ( ) ! = null )
2020-06-01 16:00:23 +02:00
url = getUrlForProduct ( CONTEXT , EntityContext . DATASET , name ) ;
2021-02-11 11:03:22 +01:00
if ( url = = null | | url . isEmpty ( ) )
url = getPortletUrl ( ) + " ? " + URLEncoder . encode ( " path=/dataset/ " + name , " UTF-8 " ) ;
2020-06-01 16:00:23 +02:00
}
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Error while retrieving dataset with id/name= " + datasetIdOrName , e ) ;
2021-02-11 11:03:22 +01:00
} // requestEntity.put("clear_url", Boolean.toString(unencrypted));
2020-06-01 16:00:23 +02:00
return url ;
}
2020-06-03 14:39:41 +02:00
2020-06-01 16:00:23 +02:00
@Override
2020-06-01 17:12:28 +02:00
public Map < String , Map < CkanGroup , RolesCkanGroupOrOrg > > getUserRoleByGroup ( String username ) {
2021-02-11 11:03:22 +01:00
LOG . info ( " Get user role by group called. The username is: " + username ) ;
2020-06-01 16:00:23 +02:00
checkNotNull ( username ) ;
2021-02-11 11:03:22 +01:00
Map < String , Map < CkanGroup , RolesCkanGroupOrOrg > > toReturn = new HashMap < String , Map < CkanGroup , RolesCkanGroupOrOrg > > ( ) ;
2020-06-01 16:00:23 +02:00
2021-02-11 11:03:22 +01:00
try {
2020-06-01 16:00:23 +02:00
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
Map < String , RolesCkanGroupOrOrg > partialResult = dbCaller . getGroupsByUserFromDB ( ckanUsername ) ;
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
for ( String groupID : partialResult . keySet ( ) ) {
CkanGroup group = ckanCaller . getGroup ( groupID ) ;
HashMap < CkanGroup , RolesCkanGroupOrOrg > subMap = new HashMap < CkanGroup , RolesCkanGroupOrOrg > ( ) ;
subMap . put ( group , partialResult . get ( groupID ) ) ;
toReturn . put ( groupID , subMap ) ;
}
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
LOG . debug ( " Returning map " + toReturn ) ;
2021-02-11 11:03:22 +01:00
LOG . info ( " Found " + toReturn . size ( ) + " group/s with the user " + username ) ;
} catch ( Exception e ) {
LOG . error ( " Failed to retrieve roles of user in his/her own groups " , e ) ;
2020-06-01 16:00:23 +02:00
}
return toReturn ;
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
}
2020-06-01 17:12:28 +02:00
@Override
2021-02-11 11:03:22 +01:00
public Map < String , Map < CkanOrganization , RolesCkanGroupOrOrg > > getUserRoleByOrganization ( String username ) {
LOG . info ( " Get user role by organization called. The username is: " + username ) ;
2020-06-01 17:12:28 +02:00
checkNotNull ( username ) ;
2021-02-11 11:03:22 +01:00
Map < String , Map < CkanOrganization , RolesCkanGroupOrOrg > > toReturn = new HashMap < String , Map < CkanOrganization , RolesCkanGroupOrOrg > > ( ) ;
2020-06-01 17:12:28 +02:00
2021-02-11 11:03:22 +01:00
try {
2020-06-01 17:12:28 +02:00
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
Map < String , RolesCkanGroupOrOrg > partialResult = dbCaller . getOrganizationsByUserFromDB ( ckanUsername ) ;
for ( String orgID : partialResult . keySet ( ) ) {
CkanOrganization org = ckanCaller . getOrganization ( orgID ) ;
HashMap < CkanOrganization , RolesCkanGroupOrOrg > subMap = new HashMap < CkanOrganization , RolesCkanGroupOrOrg > ( ) ;
subMap . put ( org , partialResult . get ( orgID ) ) ;
toReturn . put ( orgID , subMap ) ;
2021-02-11 11:03:22 +01:00
LOG . debug ( " For organisation: " + org . getName ( ) + " , the user " + username + " has role: " + subMap ) ;
2020-06-01 17:12:28 +02:00
}
LOG . debug ( " Returning map " + toReturn ) ;
2021-02-11 11:03:22 +01:00
LOG . info ( " Found " + toReturn . size ( ) + " organization/s with the user " + username ) ;
} catch ( Exception e ) {
LOG . error ( " Failed to retrieve roles of user in his/her own groups " , e ) ;
2020-06-01 17:12:28 +02:00
}
return toReturn ;
}
2020-06-01 16:00:23 +02:00
/ * *
* Retrieve an url for the tuple scope , entity , entity name
2021-02-11 11:03:22 +01:00
*
2020-06-01 16:00:23 +02:00
* @param context
* @param entityContext
* @param entityName
* /
2021-02-11 11:03:22 +01:00
private String getUrlForProduct ( String context , EntityContext entityContext , String entityName ) {
2020-06-01 16:00:23 +02:00
String toReturn = null ;
try ( CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ) {
HttpPost httpPostRequest = new HttpPost ( getUriResolverUrl ( ) ) ;
JSONObject requestEntity = new JSONObject ( ) ;
requestEntity . put ( " gcube_scope " , context ) ;
requestEntity . put ( " entity_context " , entityContext . toString ( ) ) ;
requestEntity . put ( " entity_name " , entityName ) ;
StringEntity params = new StringEntity ( requestEntity . toJSONString ( ) , ContentType . APPLICATION_JSON ) ;
httpPostRequest . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( httpPostRequest ) ;
2021-02-11 11:03:22 +01:00
if ( response . getStatusLine ( ) . getStatusCode ( ) ! = 200 )
2020-06-01 16:00:23 +02:00
throw new Exception ( " There was an error while creating an url " + response . getStatusLine ( ) ) ;
toReturn = EntityUtils . toString ( response . getEntity ( ) ) ;
LOG . debug ( " Result is " + toReturn ) ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Failed to get an url for this product " , e ) ;
}
2021-02-11 11:03:22 +01:00
return toReturn ;
2020-06-01 16:00:23 +02:00
}
2021-02-11 11:03:22 +01:00
2020-06-03 16:29:47 +02:00
@Override
public LandingPages getLandingPages ( ) throws Exception {
LandingPages landingPages = new LandingPages ( ) ;
landingPages . setUrlGroups ( PORTLET_URL_FOR_SCOPE + " ?path=/group/ " ) ;
landingPages . setUrlItems ( PORTLET_URL_FOR_SCOPE + " ?path=/dataset/ " ) ;
landingPages . setUrlOrganizations ( PORTLET_URL_FOR_SCOPE + " ?path=/organization/ " ) ;
landingPages . setUrlTypes ( PORTLET_URL_FOR_SCOPE + " ?path=/type/ " ) ;
return landingPages ;
}
2020-06-01 16:00:23 +02:00
@Override
public String getUriResolverUrl ( ) {
return URI_RESOLVER_URL ;
}
/ * *
* Check if the manage product is enabled
* @return
* /
@Override
public boolean isManageProductEnabled ( ) {
return MANAGE_PRODUCT_BUTTON ;
}
@Override
public List < CkanOrganization > getOrganizationsByUser ( String username ) {
LOG . debug ( " Requested organizations for user " + username ) ;
// checks
checkNotNull ( username ) ;
// in order to avoid errors, the username is always converted
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
// list to return
List < CkanOrganization > toReturn = new ArrayList < CkanOrganization > ( ) ;
2021-02-11 11:03:22 +01:00
try {
2021-02-09 12:55:58 +01:00
Map < String , RolesCkanGroupOrOrg > partialResult = dbCaller . getOrganizationsByUserFromDB ( ckanUsername ) ;
for ( String orgID : partialResult . keySet ( ) ) {
2021-02-11 11:03:22 +01:00
CkanOrganization org = ckanCaller . getOrganization ( orgID , false ) ;
2021-02-09 12:55:58 +01:00
LOG . debug ( " User " + ckanUsername + " is into " + org . getName ( ) ) ;
toReturn . add ( org ) ;
}
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Unable to get user's organizations " , e ) ;
}
return toReturn ;
}
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
@Override
public List < CkanGroup > getGroupsByUser ( String username ) {
LOG . debug ( " Requested groups for user " + username ) ;
// checks
checkNotNull ( username ) ;
// in order to avoid errors, the username is always converted
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
// list to return
List < CkanGroup > toReturn = new ArrayList < CkanGroup > ( ) ;
2021-02-11 11:03:22 +01:00
try {
2020-06-01 16:00:23 +02:00
2021-02-09 12:55:58 +01:00
Map < String , RolesCkanGroupOrOrg > partialResult = dbCaller . getGroupsByUserFromDB ( ckanUsername ) ;
for ( String groupID : partialResult . keySet ( ) ) {
2021-02-11 11:03:22 +01:00
CkanGroup group = ckanCaller . getGroup ( groupID , false ) ;
2021-02-09 12:55:58 +01:00
LOG . debug ( " User " + ckanUsername + " is into " + group . getName ( ) ) ;
toReturn . add ( group ) ;
}
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Unable to get user's groups " , e ) ;
}
return toReturn ;
}
2021-02-11 11:03:22 +01:00
2020-06-03 16:29:47 +02:00
@Override
2021-02-11 11:03:22 +01:00
public List < String > getOrganizationsIds ( ) {
2020-06-03 16:29:47 +02:00
List < String > toReturn = new ArrayList < String > ( ) ;
List < CkanOrganization > orgs = ckanCaller . getOrganizationList ( ) ;
for ( CkanOrganization ckanOrganization : orgs ) {
LOG . debug ( " Retrieved org " + ckanOrganization . getName ( ) ) ;
toReturn . add ( ckanOrganization . getId ( ) ) ;
}
return toReturn ;
}
@Override
2021-02-11 11:03:22 +01:00
public List < String > getOrganizationsNames ( ) {
2020-06-03 16:29:47 +02:00
List < String > toReturn = new ArrayList < String > ( ) ;
List < CkanOrganization > orgs = ckanCaller . getOrganizationList ( ) ;
for ( CkanOrganization ckanOrganization : orgs ) {
LOG . debug ( " Retrieved org " + ckanOrganization . getName ( ) ) ;
toReturn . add ( ckanOrganization . getName ( ) ) ;
}
return toReturn ;
}
@Override
public List < String > getOrganizationsNamesByUser ( String username ) {
LOG . debug ( " Requested organizations for user " + username ) ;
// checks
checkNotNull ( username ) ;
// in order to avoid errors, the username is always converted
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
List < CkanOrganization > orgs = getOrganizationsByUser ( ckanUsername ) ;
List < String > orgsName = new ArrayList < String > ( ) ;
for ( CkanOrganization ckanOrganization : orgs ) {
orgsName . add ( ckanOrganization . getName ( ) ) ;
LOG . debug ( " Organization name is " + ckanOrganization . getName ( ) ) ;
}
return orgsName ;
}
2021-02-11 11:03:22 +01:00
2020-06-03 16:29:47 +02:00
@Override
public String getRoleOfUserInOrganization ( String username , String orgName ) {
String toReturn = null ;
String apiKey = getApiKeyFromUsername ( username ) ;
String usernameCkan = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
2021-02-11 11:03:22 +01:00
try {
2020-06-03 16:29:47 +02:00
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
List < CkanUser > users = client . getOrganization ( orgName ) . getUsers ( ) ;
for ( CkanUser ckanUser : users ) {
2021-02-11 11:03:22 +01:00
if ( ckanUser . getName ( ) . equals ( usernameCkan ) ) {
2020-06-03 16:29:47 +02:00
toReturn = ckanUser . getCapacity ( ) ;
break ;
}
}
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
LOG . error ( " Unable to retrieve the role the user has into organization: " + orgName , e ) ;
2020-06-03 16:29:47 +02:00
}
return toReturn ;
}
2020-08-28 12:31:49 +02:00
/ * *
* Check if the user is valid by checking if its API_KEY is present into DB .
*
* @param username the username
* @return true , if successful
* /
@Override
public boolean checkValidUser ( String username ) {
2021-02-11 11:03:22 +01:00
2020-08-28 12:31:49 +02:00
String apiKey = getApiKeyFromUsername ( username ) ;
return apiKey ! = null ;
2021-02-11 11:03:22 +01:00
2020-08-28 12:31:49 +02:00
}
2020-06-03 16:29:47 +02:00
2020-06-01 16:00:23 +02:00
private String getApiKeyFromUsername ( String username ) {
LOG . debug ( " Request api key for user = " + username ) ;
// checks
checkNotNull ( username ) ;
checkArgument ( ! username . isEmpty ( ) ) ;
// in order to avoid errors, the username is always converted
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
// check in the hashmap first
2021-02-11 11:03:22 +01:00
if ( apiKeysMap . containsKey ( ckanUsername ) ) {
2020-06-01 16:00:23 +02:00
CKANTokenBean bean = apiKeysMap . get ( ckanUsername ) ;
2021-02-11 11:03:22 +01:00
if ( bean . timestamp + EXPIRE_KEY_TIME > System . currentTimeMillis ( ) ) { // it's still ok
2020-06-01 16:00:23 +02:00
return bean . apiKey ;
}
}
LOG . debug ( " Api key was not in cache or it expired " ) ;
2021-02-11 11:03:22 +01:00
try {
2020-06-01 16:00:23 +02:00
String apiToReturn = dbCaller . getApiKeyFromUsername ( username , State . ACTIVE . name ( ) . toLowerCase ( ) ) ;
// save into the hashmap
2021-02-11 11:03:22 +01:00
if ( apiToReturn ! = null )
2020-06-01 16:00:23 +02:00
apiKeysMap . put ( ckanUsername , new CKANTokenBean ( apiToReturn , System . currentTimeMillis ( ) ) ) ;
return apiToReturn ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-01 16:00:23 +02:00
LOG . error ( " Unable to retrieve key for user " + ckanUsername , e ) ;
}
2021-02-11 11:03:22 +01:00
2020-06-01 16:00:23 +02:00
return null ;
}
2020-06-03 14:39:41 +02:00
@Override
public boolean existProductWithNameOrId ( String nameOrId ) {
2021-02-11 11:03:22 +01:00
2020-06-03 14:39:41 +02:00
checkNotNull ( nameOrId ) ;
checkArgument ( ! nameOrId . isEmpty ( ) ) ;
2021-02-11 11:03:22 +01:00
try {
2020-06-03 14:39:41 +02:00
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , CKAN_TOKEN_SYS ) ;
CkanDataset product = client . getDataset ( nameOrId ) ;
return product ! = null ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2020-06-03 14:39:41 +02:00
LOG . debug ( " A dataset with name " + nameOrId + " doesn't exist " ) ;
return false ;
}
}
2021-02-11 11:03:22 +01:00
2020-06-03 16:29:47 +02:00
@Override
2020-08-27 14:37:19 +02:00
public CkanOrganization getOrganizationByIdOrName ( String idOrName ) {
2020-06-03 16:29:47 +02:00
2020-08-27 14:37:19 +02:00
checkNotNull ( idOrName ) ;
2020-06-03 16:29:47 +02:00
2020-08-27 14:37:19 +02:00
String ckanName = idOrName . toLowerCase ( ) ;
2021-02-11 11:03:22 +01:00
try {
2020-06-03 16:29:47 +02:00
return ckanCaller . getOrganization ( ckanName ) ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
LOG . warn ( " Failed to retrieve the organization with name " + idOrName + " on the ckan: "
+ ckanCaller . getCatalogUrl ( ) , e ) ;
2020-06-03 16:29:47 +02:00
}
return null ;
}
2020-06-03 14:39:41 +02:00
2021-02-11 11:03:22 +01:00
/ * *
* Check if the user has this role into the organization / group with
* groupOrOrganization name
*
* @param ckanUsername
* @param organizationName
* @param correspondentRoleToCheck
* @return true if he has the role , false otherwise
* /
protected boolean isRoleAlreadySet ( String ckanUsername , String groupOrOrganization ,
RolesCkanGroupOrOrg correspondentRoleToCheck , boolean group ) throws Exception {
// get the users (if you try ckanOrganization.getUsers() it returns null.. maybe
// a bug TODO)
List < CkanUser > users ;
if ( group )
users = ckanCaller . getGroup ( groupOrOrganization ) . getUsers ( ) ;
else
users = ckanCaller . getOrganization ( groupOrOrganization ) . getUsers ( ) ;
for ( CkanUser ckanUser : users ) {
if ( ckanUser . getName ( ) . equals ( ckanUsername ) )
if ( ckanUser . getCapacity ( ) . equals ( RolesCkanGroupOrOrg . convertToCkanCapacity ( correspondentRoleToCheck ) ) )
return true ;
else
break ;
}
return false ;
}
/ * *
* Just check if the group exists
*
* @param nameOrId
* @param client
* @return
* /
private CkanGroup groupExists ( String nameOrId ) {
CkanGroup toReturn = null ;
try {
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , CKAN_TOKEN_SYS ) ;
toReturn = client . getGroup ( nameOrId ) ;
} catch ( JackanException je ) {
LOG . error ( " The group " + nameOrId + " doesn't exist " ) ;
}
return toReturn ;
}
2021-02-11 16:09:17 +01:00
@Override
public List < CkanGroup > getParentGroups ( String groupName , String apiKey ) {
// checks
checkNotNull ( groupName ) ;
checkNotNull ( apiKey ) ;
try {
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , apiKey ) ;
return client . getGroup ( groupName ) . getGroups ( ) ;
} catch ( Exception e ) {
LOG . error ( " Something went wrong, returning null " , e ) ;
}
return null ;
}
@Override
public CkanOrganization getOrganizationByName ( String name ) {
checkNotNull ( name ) ;
String ckanName = name . toLowerCase ( ) ;
try {
return ckanCaller . getOrganization ( ckanName ) ;
} catch ( Exception e ) {
LOG . warn ( " Failed to retrieve the organization with name " + name + " on the ckan: " + ckanCaller . getCatalogUrl ( ) , e ) ;
}
return null ;
}
2021-02-11 11:03:22 +01:00
/ *
*
*
*
*
*
*
*
*
*
* WRITE OPERATIONS
*
*
*
*
*
*
*
*
*
*
* /
2020-06-01 16:00:23 +02:00
2021-02-09 12:55:58 +01:00
@Override
public boolean checkRoleIntoOrganization ( String username , String organizationName ,
RolesCkanGroupOrOrg correspondentRoleToCheck ) {
LOG . debug ( " Request for checking if " + username + " into organization " + organizationName + " has role " + correspondentRoleToCheck ) ;
// checks
checkNotNull ( username ) ;
checkNotNull ( organizationName ) ;
checkNotNull ( correspondentRoleToCheck ) ;
checkArgument ( ! username . isEmpty ( ) ) ;
checkArgument ( ! organizationName . isEmpty ( ) ) ;
// convert ckan username
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
// check if this role is already present in ckan for this user within the organization
String organizationNameToCheck = organizationName . toLowerCase ( ) ;
try {
boolean alreadyPresent = isRoleAlreadySet ( ckanUsername , organizationNameToCheck , correspondentRoleToCheck , false ) ;
if ( alreadyPresent )
return true ; // just return
else {
//TODO PASS by GCAT?
// we need to use the APIs to make it
String path = " /api/3/action/organization_member_create " ;
JSONObject obj = new JSONObject ( ) ;
obj . put ( " id " , organizationNameToCheck ) ;
obj . put ( " username " , ckanUsername ) ;
obj . put ( " role " , RolesCkanGroupOrOrg . convertToCkanCapacity ( correspondentRoleToCheck ) ) ;
LOG . debug ( " API request for organization membership is going to be " + obj . toJSONString ( ) ) ;
try ( CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ; ) {
HttpPost request = new HttpPost ( CKAN_CATALOGUE_URL + path ) ;
request . addHeader ( " Authorization " , CKAN_TOKEN_SYS ) ; // sys token
StringEntity params = new StringEntity ( obj . toJSONString ( ) ) ;
request . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( request ) ;
LOG . debug ( " Response code is " + response . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
return response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK ;
} catch ( Exception ex ) {
LOG . error ( " Error while trying to change the role for this user " , ex ) ;
}
}
} catch ( Exception ex ) {
LOG . error ( " Unable to check if this role was already set, please check your parameters! " , ex ) ;
}
return false ;
}
@Override
public boolean checkRoleIntoGroup ( String username , String groupName , RolesCkanGroupOrOrg correspondentRoleToCheck ) {
LOG . debug ( " Request for checking if " + username + " into group " + groupName + " has role " + correspondentRoleToCheck ) ;
// checks
checkNotNull ( username ) ;
checkNotNull ( groupName ) ;
checkNotNull ( correspondentRoleToCheck ) ;
checkArgument ( ! username . isEmpty ( ) ) ;
checkArgument ( ! groupName . isEmpty ( ) ) ;
// convert ckan username
String ckanUsername = CatalogueUtilMethods . fromUsernameToCKanUsername ( username ) ;
// check if this role is already present in ckan for this user within the group
String groupNameToCheck = CatalogueUtilMethods . fromGroupTitleToName ( groupName ) ;
try {
boolean alreadyPresent = isRoleAlreadySet ( ckanUsername , groupNameToCheck , correspondentRoleToCheck , true ) ;
if ( alreadyPresent )
return true ; // just return
else {
// we need to use the apis to make it
String path = " /api/3/action/group_member_create " ;
JSONObject obj = new JSONObject ( ) ;
obj . put ( " id " , groupNameToCheck ) ;
obj . put ( " username " , ckanUsername ) ;
obj . put ( " role " , RolesCkanGroupOrOrg . convertToCkanCapacity ( correspondentRoleToCheck ) ) ;
LOG . debug ( " API request for organization membership is going to be " + obj . toJSONString ( ) ) ;
try ( CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ; ) {
HttpPost request = new HttpPost ( CKAN_CATALOGUE_URL + path ) ;
request . addHeader ( " Authorization " , CKAN_TOKEN_SYS ) ; // sys token
StringEntity params = new StringEntity ( obj . toJSONString ( ) ) ;
request . setEntity ( params ) ;
HttpResponse response = httpClient . execute ( request ) ;
LOG . debug ( " Response code is " + response . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
return response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK ;
} catch ( Exception ex ) {
LOG . error ( " Error while trying to change the role for this user " , ex ) ;
}
}
} catch ( Exception ex ) {
LOG . error ( " Unable to check if this role was already set, please check your parameters! " , ex ) ;
}
return false ;
}
2020-06-03 14:39:41 +02:00
@Override
2021-02-09 17:55:44 +01:00
public String createCkanDatasetMultipleCustomFields ( String username , String title , String name , String organizationName ,
2020-06-03 14:39:41 +02:00
String author , String authorMail , String maintainer , String maintainerMail , long version ,
String description , String licenseId , List < String > tags , Map < String , List < String > > customFieldsMultiple ,
2020-08-28 15:29:42 +02:00
List < ResourceBean > resources , boolean setPublic , boolean setSearchable , boolean socialPost ) throws Exception {
2021-02-08 17:44:09 +01:00
LOG . info ( " Called createCkanDatasetMultipleCustomFields " ) ;
2020-08-28 15:29:42 +02:00
2020-06-03 14:39:41 +02:00
// checks (minimum)
checkNotNull ( username ) ;
2021-02-09 17:55:44 +01:00
//checkNotNull(organizationNameOrId);
//checkArgument(!organizationNameOrId.isEmpty());
2020-06-03 14:39:41 +02:00
checkArgument ( ! ( title = = null & & name = = null | | title . isEmpty ( ) & & name . isEmpty ( ) ) , " Name and Title cannot be empty/null at the same time! " ) ;
2021-02-08 17:44:09 +01:00
try {
2021-02-09 17:55:44 +01:00
2021-02-11 11:03:22 +01:00
//Business logic to pass the organization name to gCat if and only if the scope is of ROOT or VO (not VRE)
String scope = ScopeProvider . instance . get ( ) ;
if ( scope = = null )
throw new Exception ( " No scope detected. You must set it " ) ;
GCUBE_SCOPE_LEVEL gCubeScopeLevel = GCubeUtils . toGCubeLevel ( scope ) ;
String toPassOrganizationToGcat = null ;
if ( gCubeScopeLevel ! = null ) {
switch ( gCubeScopeLevel ) {
case ROOT :
case VO :
toPassOrganizationToGcat = organizationName ;
break ;
case VRE :
toPassOrganizationToGcat = null ;
default :
break ;
}
}
2021-02-09 17:55:44 +01:00
2021-02-08 17:44:09 +01:00
// String ckanUsername = getUserFromApiKey(apiKey).getName();
2021-02-11 11:03:22 +01:00
CkanDataset dataset = CKANConveter . toCkanDataset ( ckanCaller , username , title , name , toPassOrganizationToGcat , author , authorMail ,
2021-02-08 17:44:09 +01:00
maintainer , maintainerMail , version , description , licenseId , tags , null , customFieldsMultiple ,
resources , setPublic , setSearchable ) ;
2020-09-02 17:40:12 +02:00
2021-02-08 17:44:09 +01:00
// trying to create by gCat
String jsonValueDataset = MarshUnmarshCkanObject . toJsonValueDataset ( dataset , METHOD . TO_CREATE ) ;
LOG . info ( " Serialized dataset is: " + jsonValueDataset ) ;
jsonValueDataset = gCatCaller . createDataset ( jsonValueDataset , socialPost ) ;
LOG . debug ( " Created dataset is: " + jsonValueDataset ) ;
if ( jsonValueDataset ! = null ) {
CkanDataset toCkanDataset = MarshUnmarshCkanObject . toCkanDataset ( jsonValueDataset , METHOD . TO_READ ) ;
LOG . info ( " Dataset with name " + toCkanDataset . getName ( ) + " has been created correctly " ) ;
//TODO FOLLOWING OPERATIONS NOT SHOULD LONGER NEEDED ON DATASET CREATION, MUST BE CHECKED with @LUCA
// // set visibility
// boolean visibilitySet = setDatasetPrivate(
// !setPublic, // swap to private
// res.getOrganization().getId(),
// res.getId(),
// CKAN_TOKEN_SYS); // use sysadmin api key to be sure it will be set
//
// logger.info("Was visibility set to " + (setPublic ? "public" : "private") + "? " + visibilitySet);
//
// // set searchable to true if dataset visibility is private
// if(!setPublic){ // (swap to private)
// boolean searchableSet = setSearchableField(res.getId(), true);
// logger.info("Was searchable set to True? " + searchableSet);
// }
// return res.getId();
2020-08-28 15:29:42 +02:00
2020-06-05 12:42:01 +02:00
2021-02-08 17:44:09 +01:00
return toCkanDataset . getId ( ) ;
2020-06-03 14:39:41 +02:00
}
2021-02-08 17:44:09 +01:00
} catch ( Exception e ) {
LOG . error ( " Error on creating the dataset: " , e ) ;
2020-06-03 14:39:41 +02:00
}
2021-02-08 17:44:09 +01:00
return null ;
2020-08-28 15:29:42 +02:00
}
2021-02-08 17:44:09 +01:00
2021-02-11 11:03:22 +01:00
@Override
2021-02-12 14:58:23 +01:00
public boolean patchFieldsForDataset ( String datasetIdOrName , Map < String , String > mapFields ) throws Exception {
LOG . info ( " Called patch the fields " + mapFields + " for dataset id/name: " + datasetIdOrName ) ;
2021-02-11 11:03:22 +01:00
2021-02-12 14:58:23 +01:00
checkNotNull ( datasetIdOrName ) ;
2020-08-28 15:29:42 +02:00
checkNotNull ( mapFields ) ;
2021-02-11 11:03:22 +01:00
2020-08-28 15:29:42 +02:00
try {
2021-02-12 14:58:23 +01:00
CkanDataset dataset = ckanCaller . getDataset ( datasetIdOrName ) ;
String datasetId = dataset . getId ( ) ;
2020-08-28 15:29:42 +02:00
JSONObject jsonObj = new JSONObject ( ) ;
for ( String key : mapFields . keySet ( ) ) {
jsonObj . put ( key , mapFields . get ( key ) ) ;
2020-08-28 12:07:54 +02:00
}
2021-02-12 14:58:23 +01:00
jsonObj . put ( " id " , datasetId ) ;
2021-02-11 11:03:22 +01:00
2020-08-28 15:29:42 +02:00
LOG . debug ( " Json Dataset is: " + jsonObj ) ;
2021-02-12 14:58:23 +01:00
gCatCaller . patchDataset ( dataset . getName ( ) , jsonObj ) ;
2021-02-11 11:03:22 +01:00
LOG . info ( " Patch operation for dataset " + datasetId + " terminates without errors " ) ;
2020-08-28 15:29:42 +02:00
return true ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
2021-02-12 14:58:23 +01:00
LOG . error ( " Error occurred trying to patch the dataset with id: " + datasetIdOrName , e ) ;
2021-02-11 11:03:22 +01:00
throw new Exception ( " Unable to patch the dataset. Error: " + e . getMessage ( ) ) ;
2020-06-03 14:39:41 +02:00
}
2021-02-11 11:03:22 +01:00
2020-06-03 14:39:41 +02:00
}
2021-02-11 11:03:22 +01:00
2020-08-28 15:29:42 +02:00
@Override
public boolean setSearchableFieldForDataset ( String datasetId , boolean searchable ) throws Exception {
2021-02-11 11:03:22 +01:00
LOG . info ( " Set searchalbe field as " + searchable + " for dataset id: " + datasetId ) ;
2020-08-28 15:29:42 +02:00
checkNotNull ( datasetId ) ;
2021-02-11 11:03:22 +01:00
2020-08-28 15:29:42 +02:00
try {
String searchableAsString = searchable ? " True " : " False " ;
JSONObject jsonObj = new JSONObject ( ) ;
2021-02-11 11:03:22 +01:00
jsonObj . put ( " id " , datasetId ) ; // just to be sure
2020-08-28 15:29:42 +02:00
jsonObj . put ( " searchable " , searchableAsString ) ;
LOG . debug ( " Json Dataset is: " + jsonObj ) ;
gCatCaller . patchDataset ( datasetId , jsonObj ) ;
2021-02-11 11:03:22 +01:00
LOG . info ( " Set 'searchable' field for dataset " + datasetId + " terminates without errors " ) ;
2020-08-28 15:29:42 +02:00
return true ;
2021-02-11 11:03:22 +01:00
} catch ( Exception e ) {
LOG . error ( " Error occured trying to set the 'searchable' field for the dataset with id: " + datasetId ,
e . getMessage ( ) ) ;
throw new Exception ( " Unable to set the 'searchable' field for this dataset. Error: " + e . getMessage ( ) ) ;
2020-08-28 15:29:42 +02:00
}
2021-02-11 11:03:22 +01:00
2020-08-28 15:29:42 +02:00
}
2020-06-01 16:00:23 +02:00
2020-06-03 16:29:47 +02:00
@Override
public String addResourceToDataset ( ResourceBean resourceBean ) throws Exception {
2020-08-28 12:07:54 +02:00
LOG . info ( " Request to add a resource described by this bean " + resourceBean ) ;
2020-06-03 16:29:47 +02:00
// checks
checkNotNull ( resourceBean ) ;
2021-02-12 14:58:23 +01:00
checkNotNull ( resourceBean . getUrl ( ) ) ;
boolean isAccessibleURL = false ;
try {
isAccessibleURL = CatalogueUtilMethods . resourceExists ( resourceBean . getUrl ( ) ) ;
} catch ( Exception e ) {
throw new Exception ( " It seems the resource at this url " + resourceBean . getUrl ( ) + " is not reachable. Error: " + e . getMessage ( ) ) ;
}
2020-06-03 16:29:47 +02:00
2021-02-12 14:58:23 +01:00
if ( ! isAccessibleURL ) {
throw new Exception ( " It seems there is no resource at this url " + resourceBean . getUrl ( ) ) ;
}
2020-06-03 16:29:47 +02:00
2021-02-12 14:58:23 +01:00
try {
2021-02-08 17:44:09 +01:00
CkanResource resource = CKANConveter . toCkanResource ( CKAN_CATALOGUE_URL , resourceBean ) ;
2021-02-11 11:03:22 +01:00
String jsonValueResource = MarshUnmarshCkanObject . toJsonValueResource ( resource , METHOD . TO_CREATE ) ;
LOG . debug ( " Serialized resource is: " + jsonValueResource ) ;
2020-06-03 16:29:47 +02:00
jsonValueResource = gCatCaller . addResourceToDataset ( resourceBean . getDatasetId ( ) , jsonValueResource ) ;
LOG . debug ( " Added resource to dataset is: " + jsonValueResource ) ;
CkanResource createdRes = MarshUnmarshCkanObject . toCkanResource ( jsonValueResource ) ;
2021-02-11 11:03:22 +01:00
if ( createdRes ! = null ) {
LOG . debug ( " Resource " + createdRes . getName ( ) + " added correclty " ) ;
2020-06-03 16:29:47 +02:00
return createdRes . getId ( ) ;
}
2021-02-12 14:58:23 +01:00
} catch ( Exception e ) {
LOG . error ( " Unable to add the resource " + resourceBean , e ) ;
}
2020-06-03 16:29:47 +02:00
2020-06-01 16:00:23 +02:00
return null ;
}
2020-08-27 17:25:56 +02:00
@Override
public boolean deleteResourceFromDataset ( String resourceId ) throws Exception {
2020-08-28 12:07:54 +02:00
LOG . info ( " Request to delete a resource with id " + resourceId ) ;
// checks
checkNotNull ( resourceId ) ;
checkArgument ( ! resourceId . isEmpty ( ) ) ;
try {
CkanResource theResource = ckanCaller . getResource ( resourceId ) ;
gCatCaller . deleteResource ( theResource . getPackageId ( ) , resourceId ) ;
return true ;
} catch ( Exception e ) {
LOG . error ( " Unable to delete resource whose id is " + resourceId , e ) ;
}
return false ;
2020-08-27 17:25:56 +02:00
}
@Override
2020-08-28 15:29:42 +02:00
public CkanGroup createGroup ( String name , String title , String description ) throws Exception {
2020-08-27 17:25:56 +02:00
// checks
2020-08-28 15:29:42 +02:00
checkNotNull ( name ) ;
checkArgument ( ! name . trim ( ) . isEmpty ( ) ) ;
2020-08-27 17:25:56 +02:00
// check if it exists
CkanGroup toCreate = null ;
2020-08-28 15:29:42 +02:00
LOG . debug ( " Request for creating group with name " + name + " title " + title + " and description " + description ) ;
String normalizedName = CatalogueUtilMethods . fromGroupTitleToName ( name ) ;
2020-08-27 17:25:56 +02:00
if ( ( toCreate = groupExists ( name ) ) ! = null )
return toCreate ;
else {
try {
2020-08-28 15:29:42 +02:00
CkanGroup group = new CkanGroup ( normalizedName ) ;
2020-08-27 17:25:56 +02:00
group . setTitle ( title ) ;
group . setDisplayName ( title ) ;
group . setDescription ( description ) ;
String jsonValueGroup = MarshUnmarshCkanObject . toJsonValueGroup ( group ) ;
LOG . trace ( " Serialized group is: " + jsonValueGroup ) ;
String theGroup = gCatCaller . createGroup ( jsonValueGroup ) ;
toCreate = MarshUnmarshCkanObject . toCkanGroup ( theGroup ) ;
LOG . info ( " Created the group with id: " + toCreate . getId ( ) + " , name: " + toCreate . getName ( ) ) ;
} catch ( JackanException je ) {
LOG . error ( " Unable to create such group " , je ) ;
}
}
return toCreate ;
}
2021-02-11 16:09:17 +01:00
@Override
public Map < RolesCkanGroupOrOrg , List < String > > getRolesAndUsersGroup ( String groupName ) {
// checks
checkNotNull ( groupName ) ;
checkArgument ( ! groupName . isEmpty ( ) ) ;
Map < RolesCkanGroupOrOrg , List < String > > capacityAndUsers = null ;
String groupNameToCheck = CatalogueUtilMethods . fromGroupTitleToName ( groupName ) ;
CkanGroup group = ckanCaller . getGroup ( groupNameToCheck ) ;
if ( group ! = null ) {
capacityAndUsers = new HashMap < RolesCkanGroupOrOrg , List < String > > ( ) ;
List < CkanUser > users = group . getUsers ( ) ;
for ( CkanUser ckanUser : users ) {
List < String > listUsers ;
if ( capacityAndUsers . containsKey ( RolesCkanGroupOrOrg . convertFromCapacity ( ckanUser . getCapacity ( ) ) ) ) {
listUsers = capacityAndUsers . get ( RolesCkanGroupOrOrg . convertFromCapacity ( ckanUser . getCapacity ( ) ) ) ;
} else
listUsers = new ArrayList < String > ( ) ;
listUsers . add ( ckanUser . getName ( ) ) ;
capacityAndUsers . put ( RolesCkanGroupOrOrg . convertFromCapacity ( ckanUser . getCapacity ( ) ) , listUsers ) ;
}
LOG . info ( " Returning " + capacityAndUsers ) ;
}
return capacityAndUsers ;
}
//TODO HAS TO BE REVISITED by gCAT
@Override
public boolean assignDatasetToGroup ( String groupNameOrId , String datasetNameOrId ) {
return assignDatasetToGroupBody ( groupNameOrId , datasetNameOrId , false ) ;
}
/ * *
* The real body of the assignDatasetToGroup
* @param groupNameOrId
* @param datasetNameOrId
* @param apiKey
* @param addOnParents
* @return
* /
private boolean assignDatasetToGroupBody ( String groupNameOrId , String datasetNameOrId , boolean addOnParents ) {
// checks
checkNotNull ( groupNameOrId ) ;
checkArgument ( ! groupNameOrId . isEmpty ( ) ) ;
checkNotNull ( datasetNameOrId ) ;
checkArgument ( ! datasetNameOrId . isEmpty ( ) ) ;
String groupNameToCheck = CatalogueUtilMethods . fromGroupTitleToName ( groupNameOrId ) ;
try ( CloseableHttpClient httpClient = HttpClientBuilder . create ( ) . build ( ) ; ) {
ExtendCkanClient client = new ExtendCkanClient ( CKAN_CATALOGUE_URL , CKAN_TOKEN_SYS ) ;
// check the group exists
CkanGroup group = client . getGroup ( groupNameToCheck ) ;
// move to a list
List < String > groupNames = new ArrayList < String > ( ) ;
groupNames . add ( group . getName ( ) ) ;
if ( group ! = null & & addOnParents ) {
findHierarchyGroups ( groupNames , CKAN_TOKEN_SYS ) ;
}
// we need to use the apis to make it
String pathPackageShow = CKAN_CATALOGUE_URL + " /api/3/action/package_show?id= " + datasetNameOrId ;
HttpGet getRequest = new HttpGet ( pathPackageShow ) ;
getRequest . addHeader ( " Authorization " , CKAN_TOKEN_SYS ) ;
HttpResponse response = httpClient . execute ( getRequest ) ;
LOG . debug ( " Response is " + response . getStatusLine ( ) . getStatusCode ( ) + " and message is " + response . getStatusLine ( ) . getReasonPhrase ( ) ) ;
// read the json dataset and fetch the groups and fetch the groups' names, if any
if ( response . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK ) {
// parse the json and convert to java beans
String jsonAsString = EntityUtils . toString ( response . getEntity ( ) ) ;
JSONParser parser = new JSONParser ( ) ;
JSONObject json = ( JSONObject ) parser . parse ( jsonAsString ) ;
JSONObject resultJson = ( JSONObject ) json . get ( " result " ) ;
JSONArray groupsJson = ( JSONArray ) resultJson . get ( " groups " ) ;
Iterator < JSONObject > it = groupsJson . iterator ( ) ;
while ( it . hasNext ( ) ) {
JSONObject object = it . next ( ) ;
try {
if ( object . containsKey ( " name " ) )
groupNames . add ( ( String ) object . get ( " name " ) ) ;
} catch ( Exception e ) {
LOG . error ( " Error " , e ) ;
}
}
// remove duplicates
Set < String > groupNamesSet = new HashSet < String > ( groupNames ) ;
LOG . debug ( " Groups to be added are " + groupNamesSet ) ;
// now we patch the dataset with the new group
String pathUpdatePatch = CKAN_CATALOGUE_URL + " /api/3/action/package_patch " ;
JSONObject req = new JSONObject ( ) ;
req . put ( " id " , datasetNameOrId ) ;
JSONArray groups = new JSONArray ( ) ;
Iterator < String > iteratorNameSet = groupNamesSet . iterator ( ) ;
while ( iteratorNameSet . hasNext ( ) ) {
String groupName = iteratorNameSet . next ( ) ;
JSONObject groupJSON = new JSONObject ( ) ;
groupJSON . put ( " name " , groupName ) ;
groups . add ( groupJSON ) ;
}
req . put ( " groups " , groups ) ;
LOG . debug ( " Request for patch is going to be " + req . toJSONString ( ) ) ;
HttpPost request = new HttpPost ( pathUpdatePatch ) ;
request . addHeader ( " Authorization " , CKAN_TOKEN_SYS ) ;
StringEntity params = new StringEntity ( req . toJSONString ( ) ) ;
request . setEntity ( params ) ;
HttpResponse responsePatch = httpClient . execute ( request ) ;
LOG . debug ( " Response code is " + responsePatch . getStatusLine ( ) . getStatusCode ( ) + " and response message is " + responsePatch . getStatusLine ( ) . getReasonPhrase ( ) ) ;
if ( responsePatch . getStatusLine ( ) . getStatusCode ( ) = = HttpStatus . SC_OK ) {
LOG . info ( " Dataset Added to the group!! " ) ;
return true ;
}
}
} catch ( Exception e ) {
LOG . error ( " Unable to make this association " , e ) ;
}
return false ;
}
/ * *
* Find the hierarchy of trees
* @param uniqueGroups
* @param catalogue
* @param user ' s api key
* /
private void findHierarchyGroups (
List < String > groupsTitles ,
String apiKey ) {
ListIterator < String > iterator = groupsTitles . listIterator ( ) ;
while ( iterator . hasNext ( ) ) {
String group = iterator . next ( ) ;
List < CkanGroup > parents = getParentGroups ( group , apiKey ) ;
if ( parents = = null | | parents . isEmpty ( ) )
return ;
for ( CkanGroup ckanGroup : parents ) {
List < String > parentsList = new ArrayList < String > ( Arrays . asList ( ckanGroup . getName ( ) ) ) ;
findHierarchyGroups ( parentsList , apiKey ) ;
for ( String parent : parentsList ) {
iterator . add ( parent ) ;
}
}
}
}
2020-06-01 16:00:23 +02:00
}