The library has been enhanced with methods to create a dataset and add/delete a resource from this.
git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/ckan-util-library@129107 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
7a7981f797
commit
060b22960d
6
pom.xml
6
pom.xml
|
@ -93,6 +93,12 @@
|
||||||
<artifactId>gcubedatacatalogue-metadata-discovery</artifactId>
|
<artifactId>gcubedatacatalogue-metadata-discovery</artifactId>
|
||||||
<version>[0.1.0-SNAPSHOT,1.0.0-SNAPSHOT)</version>
|
<version>[0.1.0-SNAPSHOT,1.0.0-SNAPSHOT)</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.htmlparser.jericho</groupId>
|
||||||
|
<artifactId>jericho-html</artifactId>
|
||||||
|
<version>3.3</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this factory to retrieve an utility class instance associated to a particular scope.
|
* Use this factory to retrieve an utility class instance associated to a particular scope.
|
||||||
* NOTE: YOU ARE SUGGESTED TO USE THIS CLASS, DO NOT INSTANCIATE THE CkanUtils object directly.
|
* NOTE: YOU ARE SUGGESTED TO USE THIS CLASS, DO NOT INSTANCIATE THE CkanUtils OBJECT DIRECTLY.
|
||||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
*/
|
*/
|
||||||
public class CKanUtilsFactory {
|
public class CKanUtilsFactory {
|
||||||
|
@ -55,11 +55,15 @@ public class CKanUtilsFactory {
|
||||||
|
|
||||||
logger.debug("Requested catalogue utils for scope " + scope);
|
logger.debug("Requested catalogue utils for scope " + scope);
|
||||||
|
|
||||||
|
if(scope == null || scope.isEmpty()){
|
||||||
|
logger.error("Malformed scope, ignoring request");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if(instanceForScopes.containsKey(scope)){
|
if(instanceForScopes.containsKey(scope)){
|
||||||
|
|
||||||
logger.debug("Catalogue utils already cached, returning object");
|
logger.debug("Catalogue utils already cached for scope = " + scope + ", returning object");
|
||||||
return instanceForScopes.get(scope);
|
return instanceForScopes.get(scope);
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
||||||
|
@ -70,7 +74,6 @@ public class CKanUtilsFactory {
|
||||||
instanceForScopes.put(scope, utilsForScope);
|
instanceForScopes.put(scope, utilsForScope);
|
||||||
|
|
||||||
return utilsForScope;
|
return utilsForScope;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,32 @@
|
||||||
package org.gcube.datacatalogue.ckanutillibrary;
|
package org.gcube.datacatalogue.ckanutillibrary;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import net.htmlparser.jericho.Renderer;
|
||||||
|
import net.htmlparser.jericho.Segment;
|
||||||
|
import net.htmlparser.jericho.Source;
|
||||||
|
|
||||||
import org.gcube.common.encryption.StringEncrypter;
|
import org.gcube.common.encryption.StringEncrypter;
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
|
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
|
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
|
||||||
|
import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.models.STATE;
|
import org.gcube.datacatalogue.ckanutillibrary.models.STATE;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import eu.trentorise.opendata.jackan.CheckedCkanClient;
|
||||||
import eu.trentorise.opendata.jackan.CkanClient;
|
import eu.trentorise.opendata.jackan.CkanClient;
|
||||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
|
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.HttpStatus;
|
||||||
|
@ -24,14 +34,16 @@ import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.Htt
|
||||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
|
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.CloseableHttpClient;
|
||||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
|
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import eu.trentorise.opendata.jackan.model.CkanDataset;
|
||||||
import eu.trentorise.opendata.jackan.model.CkanLicense;
|
import eu.trentorise.opendata.jackan.model.CkanLicense;
|
||||||
import eu.trentorise.opendata.jackan.model.CkanOrganization;
|
import eu.trentorise.opendata.jackan.model.CkanOrganization;
|
||||||
|
import eu.trentorise.opendata.jackan.model.CkanPair;
|
||||||
|
import eu.trentorise.opendata.jackan.model.CkanResource;
|
||||||
|
import eu.trentorise.opendata.jackan.model.CkanTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the Ckan Utils implementation class.
|
* This is the Ckan Utils implementation class.
|
||||||
* @author Costantino Perciante at ISTI-CNR
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
* (costantino.perciante@isti.cnr.it)
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CKanUtilsImpl implements CKanUtilsInterface{
|
public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
|
|
||||||
|
@ -45,13 +57,14 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
private Integer CKAN_DB_PORT;
|
private Integer CKAN_DB_PORT;
|
||||||
|
|
||||||
// Connection to the db
|
// Connection to the db
|
||||||
private static Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
public CKanUtilsImpl(String scope) throws Exception{
|
public CKanUtilsImpl(String scope) throws Exception{
|
||||||
|
|
||||||
String currentScope = ScopeProvider.instance.get();
|
String currentScope = ScopeProvider.instance.get();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
ScopeProvider.instance.set(scope);
|
ScopeProvider.instance.set(scope);
|
||||||
CKanRunningCluster runningInstance = new CKanRunningCluster(scope);
|
CKanRunningCluster runningInstance = new CKanRunningCluster(scope);
|
||||||
CKAN_DB_URL = runningInstance.getDatabaseHosts().get(0);
|
CKAN_DB_URL = runningInstance.getDatabaseHosts().get(0);
|
||||||
|
@ -59,6 +72,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
CKAN_DB_USER = runningInstance.getDataBaseUser();
|
CKAN_DB_USER = runningInstance.getDataBaseUser();
|
||||||
CKAN_DB_PASSWORD = StringEncrypter.getEncrypter().decrypt(runningInstance.getDataBasePassword());
|
CKAN_DB_PASSWORD = StringEncrypter.getEncrypter().decrypt(runningInstance.getDataBasePassword());
|
||||||
logger.debug("Plain password first 3 chars are " + CKAN_DB_PASSWORD.substring(0, 3));
|
logger.debug("Plain password first 3 chars are " + CKAN_DB_PASSWORD.substring(0, 3));
|
||||||
|
|
||||||
CKAN_DB_PORT = runningInstance.getDatabasePorts().get(0);
|
CKAN_DB_PORT = runningInstance.getDatabasePorts().get(0);
|
||||||
CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0);
|
CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0);
|
||||||
|
|
||||||
|
@ -66,21 +80,29 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
Class.forName("org.postgresql.Driver");
|
Class.forName("org.postgresql.Driver");
|
||||||
connection = DriverManager.getConnection(
|
connection = DriverManager.getConnection(
|
||||||
"jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD);
|
"jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD);
|
||||||
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Error while discovering ckan information in the infrastructure", e);
|
logger.error("Error while trying to connect to ckan database/catalogue ", e);
|
||||||
}finally{
|
}finally{
|
||||||
|
|
||||||
|
// set the scope back
|
||||||
ScopeProvider.instance.set(currentScope);
|
ScopeProvider.instance.set(currentScope);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getApiKeyFromUser(String username) {
|
public String getApiKeyFromUser(String username) {
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
logger.debug("Request api key for user = " + username);
|
logger.debug("Request api key for user = " + username);
|
||||||
String apiToReturn = null;
|
String apiToReturn = null;
|
||||||
try{
|
try{
|
||||||
String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=?";
|
String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=?";
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||||
preparedStatement.setString(1, username);
|
preparedStatement.setString(1, ckanUsername);
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
|
@ -88,10 +110,10 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Unable to retrieve key for user " + username, e);
|
logger.error("Unable to retrieve key for user " + ckanUsername, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Api key retrieved for user " + username);
|
logger.debug("Api key retrieved for user " + ckanUsername);
|
||||||
return apiToReturn;
|
return apiToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +155,12 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
public List<CkanOrganization> getOrganizationsByUser(String username) {
|
public List<CkanOrganization> getOrganizationsByUser(String username) {
|
||||||
|
|
||||||
logger.debug("Requested organizations for user " + username);
|
logger.debug("Requested organizations for user " + username);
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
List<String> organizationIds = getOrganizationsIds();
|
List<String> organizationIds = getOrganizationsIds();
|
||||||
String userId = getUserIdByUsername(username);
|
String userId = getUserIdByUsername(ckanUsername);
|
||||||
|
|
||||||
// list to return
|
// list to return
|
||||||
List<CkanOrganization> toReturn = new ArrayList<CkanOrganization>();
|
List<CkanOrganization> toReturn = new ArrayList<CkanOrganization>();
|
||||||
|
@ -154,7 +180,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
// the role within the organization doesn't matter
|
// the role within the organization doesn't matter
|
||||||
logger.debug("User " + username + " belongs to organization with id " + orgId);
|
logger.debug("User " + ckanUsername + " belongs to organization with id " + orgId);
|
||||||
toReturn.add(client.getOrganization(orgId));
|
toReturn.add(client.getOrganization(orgId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +200,16 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
logger.debug("Roles to check are " + rolesToMatch);
|
logger.debug("Roles to check are " + rolesToMatch);
|
||||||
Map<String, List<ROLES_IN_ORGANIZATION>> toReturn = new HashMap<String, List<ROLES_IN_ORGANIZATION>>();
|
Map<String, List<ROLES_IN_ORGANIZATION>> toReturn = new HashMap<String, List<ROLES_IN_ORGANIZATION>>();
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
// get id from the user
|
// get id from the user
|
||||||
String userId = getUserIdByUsername(username);
|
String userId = getUserIdByUsername(ckanUsername);
|
||||||
|
|
||||||
// use the above method to require the list of user's organizations
|
// use the above method to require the list of user's organizations
|
||||||
List<CkanOrganization> usersOrganizations = getOrganizationsByUser(username);
|
List<CkanOrganization> usersOrganizations = getOrganizationsByUser(ckanUsername);
|
||||||
|
|
||||||
for (CkanOrganization ckanOrganization : usersOrganizations) {
|
for (CkanOrganization ckanOrganization : usersOrganizations) {
|
||||||
|
|
||||||
|
@ -205,7 +234,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
if(rolesToMatch.contains(ROLES_IN_ORGANIZATION.valueOf(role))){
|
if(rolesToMatch.contains(ROLES_IN_ORGANIZATION.valueOf(role))){
|
||||||
|
|
||||||
rolesIntoOrg.add(ROLES_IN_ORGANIZATION.valueOf(role));
|
rolesIntoOrg.add(ROLES_IN_ORGANIZATION.valueOf(role));
|
||||||
System.out.println("User " + username + " has role " + role + " into organization " + ckanOrganization.getName());
|
logger.debug("User " + ckanUsername + " has role " + role + " into organization " + ckanOrganization.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,11 +256,14 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
private String getUserIdByUsername(String username) {
|
private String getUserIdByUsername(String username) {
|
||||||
logger.debug("Request user id whose username is = " + username);
|
logger.debug("Request user id whose username is = " + username);
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
String userId = null;
|
String userId = null;
|
||||||
try{
|
try{
|
||||||
String query = "SELECT \"id\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
|
String query = "SELECT \"id\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||||
preparedStatement.setString(1, username);
|
preparedStatement.setString(1, ckanUsername);
|
||||||
preparedStatement.setString(2, STATE.active.toString());
|
preparedStatement.setString(2, STATE.active.toString());
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
|
@ -239,7 +271,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Unable to retrieve user with name " + username, e);
|
logger.error("Unable to retrieve user with name " + ckanUsername, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("User id retrieved");
|
logger.debug("User id retrieved");
|
||||||
|
@ -270,13 +302,6 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
super.finalize();
|
|
||||||
logger.debug("Closing connection on finalize()");
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCKANDBUrl() {
|
public String getCKANDBUrl() {
|
||||||
return CKAN_DB_URL;
|
return CKAN_DB_URL;
|
||||||
|
@ -290,7 +315,12 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
@Override
|
@Override
|
||||||
public List<String> getOrganizationsNamesByUser(String username) {
|
public List<String> getOrganizationsNamesByUser(String username) {
|
||||||
|
|
||||||
List<CkanOrganization> orgs = getOrganizationsByUser(username);
|
logger.debug("Requested organizations for user " + username);
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
|
List<CkanOrganization> orgs = getOrganizationsByUser(ckanUsername);
|
||||||
List<String> orgsName = new ArrayList<String>();
|
List<String> orgsName = new ArrayList<String>();
|
||||||
for (CkanOrganization ckanOrganization : orgs) {
|
for (CkanOrganization ckanOrganization : orgs) {
|
||||||
orgsName.add(ckanOrganization.getName());
|
orgsName.add(ckanOrganization.getName());
|
||||||
|
@ -321,7 +351,8 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLicenseTitles() {
|
public List<String> getLicenseTitles() {
|
||||||
logger.info("Request for CKAN licenses");
|
|
||||||
|
logger.debug("Request for CKAN licenses");
|
||||||
|
|
||||||
// get the url and the api key of the user
|
// get the url and the api key of the user
|
||||||
String ckanPortalUrl = getCatalogueUrl();
|
String ckanPortalUrl = getCatalogueUrl();
|
||||||
|
@ -344,18 +375,21 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setDatasetPrivate(boolean priv, String organizationId,
|
public boolean setDatasetPrivate(boolean priv, String organizationId,
|
||||||
String datasetId, String owner) {
|
String datasetId, String username) {
|
||||||
|
|
||||||
String pathSetPrivate = "/api/3/action/bulk_update_private";
|
String pathSetPrivate = "/api/3/action/bulk_update_private";
|
||||||
String pathSetPublic = "/api/3/action/bulk_update_public";
|
String pathSetPublic = "/api/3/action/bulk_update_public";
|
||||||
String token = null;
|
String token = null;
|
||||||
|
|
||||||
if(owner == null || owner.isEmpty()){
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
|
if(ckanUsername == null || ckanUsername.isEmpty()){
|
||||||
logger.error("The owner parameter is mandatory");
|
logger.error("The owner parameter is mandatory");
|
||||||
return false;
|
return false;
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
token = getApiKeyFromUser(owner);
|
token = getApiKeyFromUser(ckanUsername);
|
||||||
|
|
||||||
if(token == null){
|
if(token == null){
|
||||||
logger.error("Unable to retrieve user's token");
|
logger.error("Unable to retrieve user's token");
|
||||||
|
@ -414,4 +448,280 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to check if a something at this url actually exists
|
||||||
|
* @param URLName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static boolean exists(String URLName){
|
||||||
|
try {
|
||||||
|
HttpURLConnection.setFollowRedirects(true);
|
||||||
|
HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
|
||||||
|
con.setRequestMethod("HEAD");
|
||||||
|
logger.debug("Return code is " + con.getResponseCode());
|
||||||
|
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
logger.error("Exception while checking url", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String addResourceToDataset(ResourceBean resourceBean) {
|
||||||
|
|
||||||
|
logger.debug("Request to add a resource described by this bean " + resourceBean);
|
||||||
|
|
||||||
|
try{
|
||||||
|
if(exists(resourceBean.getUrl())){
|
||||||
|
|
||||||
|
// retrieve ckan's catalog url
|
||||||
|
String ckanPortalUrl = getCatalogueUrl();
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(resourceBean.getOwner());
|
||||||
|
|
||||||
|
// retrieve the api key for this user
|
||||||
|
String apiKey = getApiKeyFromUser(ckanUsername);
|
||||||
|
|
||||||
|
CkanResource resource = new CkanResource(ckanPortalUrl, resourceBean.getDatasetId());
|
||||||
|
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
|
||||||
|
CheckedCkanClient client = new CheckedCkanClient(ckanPortalUrl, apiKey);
|
||||||
|
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
|
||||||
|
public boolean deleteResourceFromDataset(String username, String resourceId) {
|
||||||
|
|
||||||
|
logger.error("Request to delete a resource with id " + resourceId + " coming by user " + username);
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
CheckedCkanClient client = new CheckedCkanClient(getCatalogueUrl(), getApiKeyFromUser(ckanUsername));
|
||||||
|
client.deleteResource(resourceId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}catch(Exception e){
|
||||||
|
logger.error("Unable to delete resource whose id is " + resourceId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the catalogue's dataset name from its title
|
||||||
|
* @param title
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String nameFromTitle(String title) {
|
||||||
|
String convertedName = title.replaceAll(" ", "_");
|
||||||
|
convertedName = convertedName.replaceAll("\\.", "_");
|
||||||
|
convertedName = convertedName.toLowerCase();
|
||||||
|
if(convertedName.endsWith("_"))
|
||||||
|
convertedName = convertedName.substring(0, convertedName.length() - 2);
|
||||||
|
|
||||||
|
return convertedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createCKanDataset(String username, String withId,
|
||||||
|
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");
|
||||||
|
|
||||||
|
// in order to avoid errors, the username is always converted
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
|
CheckedCkanClient client = new CheckedCkanClient(getCatalogueUrl(), getApiKeyFromUser(ckanUsername));
|
||||||
|
|
||||||
|
// create the base dataset and fill it
|
||||||
|
CkanDataset dataset = new CkanDataset();
|
||||||
|
|
||||||
|
// set values
|
||||||
|
dataset.setId(withId);
|
||||||
|
|
||||||
|
// get the name from the title
|
||||||
|
dataset.setName(nameFromTitle(title));
|
||||||
|
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){
|
||||||
|
|
||||||
|
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
|
||||||
|
logger.error("Error while creating the dataset, probably it already exists.", e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrlFromDatasetIdOrName(String username, String datasetIdOrName) {
|
||||||
|
|
||||||
|
logger.debug("Request coming for dataset url of dataset with name/id " + datasetIdOrName);
|
||||||
|
|
||||||
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
||||||
|
|
||||||
|
// the url of the dataset looks like "getCatalogueUrl() + /dataset/ + dataset name"
|
||||||
|
try{
|
||||||
|
CheckedCkanClient client = new CheckedCkanClient(getCatalogueUrl(), getApiKeyFromUser(ckanUsername));
|
||||||
|
CkanDataset dataset = client.getDataset(datasetIdOrName);
|
||||||
|
|
||||||
|
if(dataset != null){
|
||||||
|
return getCatalogueUrl() + "/dataset/" + dataset.getName();
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
logger.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ckan username has _ instead of . (that is, costantino.perciante -> costantino_perciante)
|
||||||
|
* @param owner
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String fromOwnerToCKanOwner(String owner){
|
||||||
|
return owner.replaceAll("\\.", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
super.finalize();
|
||||||
|
logger.debug("Closing connection on finalize()");
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
|
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
|
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
|
||||||
|
import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean;
|
||||||
|
|
||||||
import eu.trentorise.opendata.jackan.model.CkanOrganization;
|
import eu.trentorise.opendata.jackan.model.CkanOrganization;
|
||||||
|
|
||||||
|
@ -85,4 +86,49 @@ public interface CKanUtilsInterface {
|
||||||
*/
|
*/
|
||||||
public boolean setDatasetPrivate(boolean priv, String organizationId, String datasetId, String owner);
|
public boolean setDatasetPrivate(boolean priv, String organizationId, String datasetId, String owner);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a resource described by the bean to the dataset id into resource.datasetId
|
||||||
|
* @param resource
|
||||||
|
* @return String the id of the resource on success, null otherwise
|
||||||
|
*/
|
||||||
|
public String addResourceToDataset(ResourceBean resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the resource with id resourceId from the dataset in which it is.
|
||||||
|
* @param username
|
||||||
|
* @param resourceId
|
||||||
|
* @return true on success, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean deleteResourceFromDataset(String username, String resourceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a dataset with those information.
|
||||||
|
* @param username
|
||||||
|
* @param withId
|
||||||
|
* @param title
|
||||||
|
* @param organizationNameOrId
|
||||||
|
* @param author
|
||||||
|
* @param authorMail
|
||||||
|
* @param maintainer
|
||||||
|
* @param maintainerMail
|
||||||
|
* @param version
|
||||||
|
* @param description
|
||||||
|
* @param licenseId
|
||||||
|
* @param tags
|
||||||
|
* @param customFields
|
||||||
|
* @param resources
|
||||||
|
* @param setPublic (manage visibility)
|
||||||
|
* @return the id of the dataset on success, null otherwise
|
||||||
|
*/
|
||||||
|
public String createCKanDataset(String username, String withId, 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the id or the name of the dataset it returns its current url (e.g., http://ckan-catalogue-address.org/dataset/dataset-name)
|
||||||
|
* @param username
|
||||||
|
* @param datasetId
|
||||||
|
* @return The url of the dataset on success, null otherwise
|
||||||
|
*/
|
||||||
|
public String getUrlFromDatasetIdOrName(String username, String datasetIdOrName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
package org.gcube.datacatalogue.ckanutillibrary.models;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bean that resembles the CKanResource bean object
|
||||||
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
|
*/
|
||||||
|
public class ResourceBean implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5275448097250176185L;
|
||||||
|
private String url;
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private String id;
|
||||||
|
private String owner;
|
||||||
|
private String datasetId;
|
||||||
|
private String mimeType;
|
||||||
|
|
||||||
|
public ResourceBean(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url
|
||||||
|
* @param name
|
||||||
|
* @param description
|
||||||
|
* @param id
|
||||||
|
* @param owner
|
||||||
|
* @param datasetId
|
||||||
|
* @param mimeType
|
||||||
|
*/
|
||||||
|
public ResourceBean(String url, String name, String description, String id,
|
||||||
|
String owner, String datasetId, String mimeType) {
|
||||||
|
super();
|
||||||
|
this.url = url;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.id = id;
|
||||||
|
this.owner = owner;
|
||||||
|
this.datasetId = datasetId;
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the url
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url the url to set
|
||||||
|
*/
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the description
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description the description to set
|
||||||
|
*/
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the owner
|
||||||
|
*/
|
||||||
|
public String getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param owner the owner to set
|
||||||
|
*/
|
||||||
|
public void setOwner(String owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the datasetId
|
||||||
|
*/
|
||||||
|
public String getDatasetId() {
|
||||||
|
return datasetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param datasetId the datasetId to set
|
||||||
|
*/
|
||||||
|
public void setDatasetId(String datasetId) {
|
||||||
|
this.datasetId = datasetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the mimeType
|
||||||
|
*/
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mimeType the mimeType to set
|
||||||
|
*/
|
||||||
|
public void setMimeType(String mimeType) {
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ResourceBean [url=" + url + ", name=" + name + ", description="
|
||||||
|
+ description + ", id=" + id + ", owner=" + owner
|
||||||
|
+ ", datasetId=" + datasetId + ", mimeType=" + mimeType + "]";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue