diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..5cca4e3
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..7d02ff7
--- /dev/null
+++ b/.project
@@ -0,0 +1,36 @@
+
+
+ ckan-util-library
+
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..f9fe345
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..443e085
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..6bb5ced
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..1b22d70
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs
new file mode 100644
index 0000000..04cad8c
--- /dev/null
+++ b/.settings/org.eclipse.wst.validation.prefs
@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1
diff --git a/distro/LICENSE b/distro/LICENSE
new file mode 100644
index 0000000..2d9616a
--- /dev/null
+++ b/distro/LICENSE
@@ -0,0 +1 @@
+${gcube.license}
\ No newline at end of file
diff --git a/distro/README b/distro/README
new file mode 100644
index 0000000..38d5603
--- /dev/null
+++ b/distro/README
@@ -0,0 +1,62 @@
+The gCube System - ${name}
+--------------------------------------------------
+
+${description}
+
+
+${gcube.description}
+
+${gcube.funding}
+
+
+Version
+--------------------------------------------------
+
+${version} (${buildDate})
+
+Please see the file named "changelog.xml" in this directory for the release notes.
+
+
+Authors
+--------------------------------------------------
+
+* Costantino Perciante (costantino.perciante@isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
+
+Maintainers
+-----------
+
+* Costantino Perciante (costantino.perciante@isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
+
+Download information
+--------------------------------------------------
+
+Source code is available from SVN:
+ ${scm.url}
+
+Binaries can be downloaded from the gCube website:
+ ${gcube.website}
+
+
+Installation
+--------------------------------------------------
+
+Installation documentation is available on-line in the gCube Wiki:
+ ${gcube.wikiRoot}
+
+Documentation
+--------------------------------------------------
+
+Documentation is available on-line in the gCube Wiki:
+ ${gcube.wikiRoot}
+
+Support
+--------------------------------------------------
+
+Bugs and support requests can be reported in the gCube issue tracking tool:
+ ${gcube.issueTracking}
+
+
+Licensing
+--------------------------------------------------
+
+This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
\ No newline at end of file
diff --git a/distro/changelog.xml b/distro/changelog.xml
new file mode 100644
index 0000000..33d0290
--- /dev/null
+++ b/distro/changelog.xml
@@ -0,0 +1,5 @@
+
+
+ First Release
+
+
diff --git a/distro/descriptor.xml b/distro/descriptor.xml
new file mode 100644
index 0000000..b3f5628
--- /dev/null
+++ b/distro/descriptor.xml
@@ -0,0 +1,31 @@
+
+ servicearchive
+
+ tar.gz
+
+ /
+
+
+ ${distroDirectory}
+ /
+ true
+
+ README
+ LICENSE
+ changelog.xml
+ profile.xml
+
+ 755
+ true
+
+
+
+
+
+ /${artifactId}
+
+
+
\ No newline at end of file
diff --git a/distro/profile.xml b/distro/profile.xml
new file mode 100644
index 0000000..19466d1
--- /dev/null
+++ b/distro/profile.xml
@@ -0,0 +1,25 @@
+
+
+
+ Service
+
+ ${Description}
+ DataAccess
+ ${artifactId}
+ ${version}
+
+
+ ${artifactId}
+ ${version}
+
+ ${groupId}
+ ${artifactId}
+ ${version}
+
+
+ target/${build.finalName}.jar
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..8ad54d8
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,187 @@
+
+ 4.0.0
+
+
+ maven-parent
+ org.gcube.tools
+ 1.0.0
+
+
+ org.gcube.data-catalogue
+ ckan-util-library
+ 1.0.0-SNAPSHOT
+ jar
+
+ CKan utility library
+
+ Utility library to retrieve users information, organizations information and so on from the ckan d4science database.
+
+
+
+ distro
+ 1.7
+ 1.7
+ 0.4.2
+ 9.4.1208.jre7
+ UTF-8
+ UTF-8
+
+
+
+
+ org.gcube.distribution
+ maven-portal-bom
+ LATEST
+ pom
+ import
+
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+ org.slf4j
+ slf4j-simple
+ 1.6.4
+
+
+ org.postgresql
+ postgresql
+ ${postgresVersion}
+
+
+
+ eu.trentorise.opendata
+ jackan
+ ${jackanVersion}
+ compile
+
+
+ junit
+ junit
+ 4.8
+ test
+
+
+ org.gcube.common.portal
+ portal-manager
+ provided
+
+
+ org.gcube.resources.discovery
+ ic-client
+ provided
+
+
+ org.gcube.core
+ common-encryption
+ provided
+
+
+ org.gcube.core
+ common-scope-maps
+ provided
+
+
+
+
+
+
+
+ src/main/java
+
+ **/*.*
+
+
+
+
+
+ maven-compiler-plugin
+
+
+ 1.7
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.2
+
+
+
+ test-jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.12
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 2.5
+
+
+ copy-profile
+ install
+
+ copy-resources
+
+
+ target
+
+
+ ${distroDirectory}
+ true
+
+ profile.xml
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.2
+
+
+ ${distroDirectory}/descriptor.xml
+
+
+
+ fully.qualified.MainClass
+
+
+
+
+
+
+
+
+ servicearchive
+ install
+
+ single
+
+
+
+
+
+
+
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanRunningCluster.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanRunningCluster.java
new file mode 100644
index 0000000..5348f0f
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanRunningCluster.java
@@ -0,0 +1,169 @@
+package org.gcube.datacatalogue.ckanutillibrary;
+
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.gcube.common.portal.PortalContext;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.datacatalogue.ckanutillibrary.exceptions.NoCKanRuntimeResourceException;
+import org.gcube.datacatalogue.ckanutillibrary.exceptions.ServiceEndPointException;
+import org.gcube.datacatalogue.ckanutillibrary.exceptions.TooManyRunningClustersException;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Retrieve ckan running instance information in the infrastructure.
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class CKanRunningCluster {
+
+ //logger
+ private static final Logger logger = LoggerFactory.getLogger(CKanRunningCluster.class);
+
+ //properties
+ private final static String RUNTIME_RESOURCE_NAME = "CKanDatabase";
+ private final static String PLATFORM_NAME = "postgres";
+
+ // retrieved data
+ private List hosts = new ArrayList();
+ private List ports = new ArrayList();
+ private String dbName;
+ private String dbUser;
+ private String dbPassword;
+
+ public CKanRunningCluster(String infrastructure) throws Exception{
+
+ try {
+
+ List resources = getConfigurationFromIS(infrastructure);
+
+ if (resources.size() > 1) {
+ logger.error("Too many Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" in this scope");
+ throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name "
+ + RUNTIME_RESOURCE_NAME + " and Platform " + PLATFORM_NAME + ". Only one allowed per infrasrtucture.");
+ }
+ else if (resources.size() == 0){
+ logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Platform " + PLATFORM_NAME + " in this scope.");
+ throw new NoCKanRuntimeResourceException();
+ }
+ else {
+
+ try{
+
+ logger.debug(resources.toString());
+ for (ServiceEndpoint res : resources) {
+
+ Iterator accessPointIterator = res.profile().accessPoints().iterator();
+
+ while (accessPointIterator.hasNext()) {
+ ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
+ .next();
+
+ // add this host
+ hosts.add(accessPoint.address().split(":")[0]);
+
+ // save the port
+ int port = Integer.parseInt(accessPoint.address().split(":")[1]);
+ ports.add(port);
+
+ // save the name of the cluster (this should be unique)
+ dbName = accessPoint.name();
+
+ // save user and password
+ dbPassword = accessPoint.password();
+ dbUser = accessPoint.username();
+
+ break;
+
+ }
+ }
+ }catch(Exception e ){
+
+ logger.error(e.toString());
+ throw new ServiceEndPointException();
+ }
+ }
+ } catch (Exception e) {
+ logger.error(e.toString());
+ throw e;
+ }
+
+ }
+
+ /**
+ * Retrieve endpoints information from IS
+ * @return list of endpoints for ckan
+ * @throws Exception
+ */
+ private List getConfigurationFromIS(String infrastructure) throws Exception{
+
+ String scope = "";
+ if(infrastructure != null && !infrastructure.isEmpty())
+ scope += infrastructure;
+ else{
+
+ PortalContext context = PortalContext.getConfiguration();
+ scope += context.getInfrastructureName();
+
+ }
+
+ String currScope = ScopeProvider.instance.get();
+ ScopeProvider.instance.set(scope);
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_RESOURCE_NAME +"'");
+ query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_NAME +"'");
+ DiscoveryClient client = clientFor(ServiceEndpoint.class);
+ List toReturn = client.submit(query);
+ ScopeProvider.instance.set(currScope);
+ return toReturn;
+
+ }
+
+ /**
+ * Get the hosts for such resource.
+ * @return
+ */
+ public List getHosts() {
+ return hosts;
+ }
+
+ /**
+ * Get the ports for such resource.
+ * @return
+ */
+ public List getPorts() {
+ return ports;
+ }
+
+ /**
+ * Get the database name.
+ * @return
+ */
+ public String getDataBaseName() {
+ return dbName;
+ }
+
+ /**
+ * Get the database's user.
+ * @return
+ */
+ public String getDataBaseUser() {
+ return dbUser;
+ }
+
+ /**
+ * Get the database's password.
+ * @return
+ */
+ public String getDataBasePassword() {
+ return dbPassword;
+ }
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsFactory.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsFactory.java
new file mode 100644
index 0000000..540fcc7
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsFactory.java
@@ -0,0 +1,80 @@
+package org.gcube.datacatalogue.ckanutillibrary;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 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.
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class CKanUtilsFactory {
+
+ /**
+ * logger
+ */
+ private static final Logger logger = LoggerFactory.getLogger(CKanUtilsFactory.class);
+
+ /**
+ * map
+ */
+ private static Map instanceForScopes;
+
+ /**
+ * this object singleton instance
+ */
+ private static CKanUtilsFactory factoryInstance = new CKanUtilsFactory();
+
+ /**
+ * private constructor
+ */
+ private CKanUtilsFactory(){
+
+ logger.debug("Instanciating factory");
+ instanceForScopes = new HashMap();
+
+ }
+
+ /**
+ * Get the factory object
+ */
+ public static CKanUtilsFactory getInstance(){
+
+ return factoryInstance;
+
+ }
+
+ /**
+ * Retrieve catalogue utils class for this scope
+ * @param scope
+ * @throws Exception
+ */
+ public CKanUtilsImpl getCkanUtilsForScope(String scope) throws Exception{
+
+ logger.debug("Requested catalogue utils for scope " + scope);
+
+ synchronized (instanceForScopes) {
+
+ if(instanceForScopes.containsKey(scope)){
+
+ logger.debug("Catalogue utils already cached, returning object");
+ return instanceForScopes.get(scope);
+
+ }
+ else{
+
+ logger.debug("Instanciating utils for this scope");
+ CKanUtilsImpl utilsForScope = new CKanUtilsImpl("/gcube");
+
+ // save into the map
+ instanceForScopes.put(scope, utilsForScope);
+
+ return utilsForScope;
+
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsImpl.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsImpl.java
new file mode 100644
index 0000000..1fac079
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsImpl.java
@@ -0,0 +1,322 @@
+package org.gcube.datacatalogue.ckanutillibrary;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.gcube.common.encryption.StringEncrypter;
+import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
+import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
+import org.gcube.datacatalogue.ckanutillibrary.models.STATE;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.trentorise.opendata.jackan.CkanClient;
+import eu.trentorise.opendata.jackan.model.CkanLicense;
+import eu.trentorise.opendata.jackan.model.CkanOrganization;
+
+/**
+ * This is the Ckan Utils implementation class.
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ *
+ */
+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;
+ private Integer CKAN_DB_PORT;
+
+ // Connection to the db
+ private static Connection connection;
+
+ public CKanUtilsImpl(String scope) throws Exception{
+
+ CKanRunningCluster runningInstance = new CKanRunningCluster(scope);
+ CKAN_CATALOGUE_URL = runningInstance.getHosts().get(0);
+ CKAN_DB_NAME = runningInstance.getDataBaseName();
+ CKAN_DB_USER = runningInstance.getDataBaseUser();
+ CKAN_DB_PASSWORD = StringEncrypter.getEncrypter().decrypt(runningInstance.getDataBasePassword(), scope);
+ CKAN_DB_PORT = runningInstance.getPorts().get(0);
+
+ // create db connection
+ Class.forName("org.postgresql.Driver");
+ connection = DriverManager.getConnection(
+ "jdbc:postgresql://" + CKAN_CATALOGUE_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD);
+
+ }
+
+ @Override
+ public String getApiKeyFromUser(String username) {
+ logger.debug("Request api key for user = " + username);
+ String apiToReturn = null;
+ try{
+ String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=?";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, username);
+
+ ResultSet rs = preparedStatement.executeQuery();
+ while (rs.next()) {
+ apiToReturn = rs.getString("apikey");
+ break;
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve key for user " + username, e);
+ }
+
+ logger.debug("Api key retrieved for user " + username);
+ return apiToReturn;
+ }
+
+ @Override
+ public CKanUserWrapper getUserFromApiKey(String apiKey) {
+ logger.debug("Request user whose api key is = " + apiKey);
+ CKanUserWrapper user = new CKanUserWrapper();
+ try{
+ String query = "SELECT * FROM \"user\" WHERE \"apikey\"=?;";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, apiKey);
+ ResultSet rs = preparedStatement.executeQuery();
+ while (rs.next()) {
+
+ // check if it is active
+ if(STATE.deleted.equals(rs.getString("state")))
+ break;
+
+ 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"));
+ break;
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve user with api key " + apiKey);
+ }
+
+ logger.debug("User retrieved");
+ return user;
+ }
+
+ @Override
+ public List getOrganizationsByUser(String username) {
+
+ logger.debug("Requested organizations for user " + username);
+ List organizationIds = getOrganizationsIds();
+ String userId = getUserIdByUsername(username);
+
+ // list to return
+ List toReturn = new ArrayList();
+
+ // get the CkanClient to retrieve the organization from the id
+ CkanClient client = new CkanClient("https://ckan-d-d4s.d4science.org");
+
+ try{
+ // for each org id, check if the user is included
+ for (String orgId : organizationIds) {
+ String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=?; ";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, userId);
+ preparedStatement.setString(2, orgId);
+ preparedStatement.setString(3, "user");
+
+ ResultSet rs = preparedStatement.executeQuery();
+ while (rs.next()) {
+ // the role within the organization doesn't matter
+ logger.debug("User " + username + " belongs to organization with id " + orgId);
+ toReturn.add(client.getOrganization(orgId));
+ }
+
+ }
+ }catch(Exception e){
+ logger.error("Unable to get user's organizations", e);
+ }
+ return toReturn;
+ }
+
+
+ @Override
+ public Map> getGroupsAndRolesByUser(
+ String username, List rolesToMatch) {
+
+ logger.debug("Requested roles the user " + username + " has into its organizations");
+ logger.debug("Roles to check are " + rolesToMatch);
+ Map> toReturn = new HashMap>();
+
+ try{
+
+ // get id from the user
+ String userId = getUserIdByUsername(username);
+
+ // use the above method to require the list of user's organizations
+ List usersOrganizations = getOrganizationsByUser(username);
+
+ for (CkanOrganization ckanOrganization : usersOrganizations) {
+
+ // get the org id
+ String orgId = ckanOrganization.getId();
+
+ // go to the member table, that says which role has this user into the org
+ String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=?;";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, userId);
+ preparedStatement.setString(2, orgId);
+ preparedStatement.setString(3, "user");
+ ResultSet rs = preparedStatement.executeQuery();
+
+ // prepare the data to put into the hashmap
+ List rolesIntoOrg = new ArrayList();
+
+ while(rs.next()){
+
+ // check
+ String role = rs.getString("capacity");
+ if(rolesToMatch.contains(ROLES_IN_ORGANIZATION.valueOf(role))){
+
+ rolesIntoOrg.add(ROLES_IN_ORGANIZATION.valueOf(role));
+ System.out.println("User " + username + " has role " + role + " into organization " + ckanOrganization.getName());
+ }
+ }
+
+ if(!rolesIntoOrg.isEmpty())
+ toReturn.put(orgId, rolesIntoOrg);
+ }
+ }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);
+
+ String userId = null;
+ try{
+ String query = "SELECT \"id\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, username);
+ preparedStatement.setString(2, STATE.active.toString());
+ ResultSet rs = preparedStatement.executeQuery();
+ while (rs.next()) {
+ userId = rs.getString("id");
+ break;
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve user with name " + username);
+ }
+
+ logger.debug("User id retrieved");
+ return userId;
+ }
+
+ /**
+ * Retrieve the list of organizations ids
+ * @return
+ */
+ private List getOrganizationsIds(){
+ logger.debug("Request organization ids");
+ List toReturn = new ArrayList();
+
+ try{
+ String query = "SELECT \"id\" FROM \"group\" WHERE \"is_organization\"=? and \"state\"=?;";
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setBoolean(1, true);
+ preparedStatement.setString(2, STATE.active.toString());
+ ResultSet rs = preparedStatement.executeQuery();
+ while (rs.next()) {
+ toReturn.add(rs.getString("id"));
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve list of organization ids");
+ }
+
+ logger.debug("Organizations' ids retrieved");
+ return toReturn;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ logger.debug("Closing connection on finalize()");
+ connection.close();
+ }
+
+ @Override
+ public String getCatalogueUrl() {
+ return "https://" + CKAN_CATALOGUE_URL;
+ }
+
+ @Override
+ public List getOrganizationsNamesByUser(String username) {
+
+ List orgs = getOrganizationsByUser(username);
+ List orgsName = new ArrayList();
+ for (CkanOrganization ckanOrganization : orgs) {
+ orgsName.add(ckanOrganization.getName());
+ logger.debug("Organization name is " + ckanOrganization.getName());
+ }
+
+ return orgsName;
+
+ }
+
+ @Override
+ public String findLicenseIdByLicense(String chosenLicense) {
+ logger.debug("Requested license id");
+
+ String ckanPortalUrl = getCatalogueUrl();
+ CkanClient client = new CkanClient(ckanPortalUrl);
+
+ //retrieve the list of available licenses
+ List licenses = client.getLicenseList();
+
+ for (CkanLicense ckanLicense : licenses) {
+ if(ckanLicense.getTitle().equals(chosenLicense))
+ return ckanLicense.getId();
+ }
+
+ return null;
+ }
+
+ @Override
+ public List getLicenseTitles() {
+ logger.info("Request for CKAN licenses");
+
+ // get the url and the api key of the user
+ String ckanPortalUrl = getCatalogueUrl();
+ List result = new ArrayList();
+
+ CkanClient client = new CkanClient(ckanPortalUrl);
+
+ //retrieve the list of available licenses
+ List licenses = client.getLicenseList();
+
+ for (CkanLicense ckanLicense : licenses) {
+
+ result.add(ckanLicense.getTitle());
+ logger.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId());
+
+ }
+
+ return result;
+ }
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsInterface.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsInterface.java
new file mode 100644
index 0000000..9c53e8c
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsInterface.java
@@ -0,0 +1,73 @@
+package org.gcube.datacatalogue.ckanutillibrary;
+
+import java.util.List;
+import java.util.Map;
+
+import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
+import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
+
+import eu.trentorise.opendata.jackan.model.CkanOrganization;
+
+/**
+ * This is the ckan-util-library interface that shows the utility methods.
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public interface CKanUtilsInterface {
+
+ /**
+ * Retrieve the API_KEY given the username .
+ * @param username
+ * @return an API_KEY string
+ */
+ public String getApiKeyFromUser(String username);
+
+ /**
+ * Retrieve the user given the API_KEY (the user is retrieved if it is active).
+ * @param username
+ * @return an API_KEY string
+ */
+ public CKanUserWrapper getUserFromApiKey(String apiKey);
+
+ /**
+ * Returns the list of organizations to whom the user belongs.
+ * @param username
+ * @return a list of organizations
+ */
+ public List getOrganizationsByUser(String username);
+
+ /**
+ * Returns the list of organizations' names to whom the user belongs.
+ * @param username
+ * @return a list of organizations
+ */
+ public List getOrganizationsNamesByUser(String username);
+
+ /**
+ * Given a username and a list of roles to be matched, find the organizations to who the user
+ * belongs and the role(s) he has in them.
+ * @param username
+ * @param rolesToMatch
+ * @return
+ */
+ public Map> getGroupsAndRolesByUser(String username, List rolesToMatch);
+
+ /**
+ * Return the ckan catalogue url in this scope.
+ * @return
+ */
+ public String getCatalogueUrl();
+
+ /**
+ * Get the list of licenses' titles.
+ * @return
+ */
+ public List getLicenseTitles();
+
+ /**
+ * Finds the id associated to the chosen license
+ * @param chosenLicense
+ * @return
+ */
+ public String findLicenseIdByLicense(String chosenLicense);
+
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/NoCKanRuntimeResourceException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/NoCKanRuntimeResourceException.java
new file mode 100644
index 0000000..af39a8f
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/NoCKanRuntimeResourceException.java
@@ -0,0 +1,24 @@
+package org.gcube.datacatalogue.ckanutillibrary.exceptions;
+
+/**
+ * No elasticsearch cluster in the infrastructure found exception.
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ *
+ */
+public class NoCKanRuntimeResourceException extends Exception {
+
+ private static final long serialVersionUID = -40748130477807648L;
+
+ private static final String DEFAULT_MESSAGE = "No CKan catalogue instance for this scope!";
+
+ public NoCKanRuntimeResourceException(){
+ super(DEFAULT_MESSAGE);
+ }
+
+ public NoCKanRuntimeResourceException(String message) {
+ super(message);
+ }
+
+
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/ServiceEndPointException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/ServiceEndPointException.java
new file mode 100644
index 0000000..a15e6a4
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/ServiceEndPointException.java
@@ -0,0 +1,21 @@
+package org.gcube.datacatalogue.ckanutillibrary.exceptions;
+
+/**
+ * Exception thrown when it is not possible retrieve information from the ServiceEndpoint
+ * related to ElasticSearch
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ *
+ */
+public class ServiceEndPointException extends Exception {
+
+ private static final long serialVersionUID = 7057074369001221035L;
+ private static final String DEFAULT_MESSAGE = "Unable to retrieve information from CKan endpoint!";
+
+ public ServiceEndPointException(){
+ super(DEFAULT_MESSAGE);
+ }
+ public ServiceEndPointException(String string) {
+ super(string);
+ }
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/TooManyRunningClustersException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/TooManyRunningClustersException.java
new file mode 100644
index 0000000..57901cc
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/exceptions/TooManyRunningClustersException.java
@@ -0,0 +1,22 @@
+package org.gcube.datacatalogue.ckanutillibrary.exceptions;
+
+/**
+ * Too many clusters in this scope exception.
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ *
+ */
+public class TooManyRunningClustersException extends Exception {
+
+ private static final long serialVersionUID = -7847493730006647045L;
+ private static final String DEFAULT_MESSAGE = "Too many CKan data catalague instances for this scope!";
+
+ public TooManyRunningClustersException(){
+ super(DEFAULT_MESSAGE);
+ }
+
+ public TooManyRunningClustersException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/CKanUserWrapper.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/CKanUserWrapper.java
new file mode 100644
index 0000000..8e23343
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/CKanUserWrapper.java
@@ -0,0 +1,134 @@
+package org.gcube.datacatalogue.ckanutillibrary.models;
+
+import java.io.Serializable;
+
+/**
+ * A CKan user.
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class CKanUserWrapper implements Serializable{
+
+ private static final long serialVersionUID = 6264706263035722775L;
+
+ private String id;
+ private String name;
+ private String apiKey;
+ private long creationTimestamp;
+ private String about;
+ private String openId;
+ private String fullName;
+ private String email;
+ private boolean isAdmin;
+
+
+ public CKanUserWrapper() {
+ super();
+ }
+
+ /** Create a ckan user object.
+ * @param id
+ * @param name
+ * @param apiKey
+ * @param creationTimestamp
+ * @param about
+ * @param openId
+ * @param fullName
+ * @param email
+ * @param isAdmin
+ */
+ public CKanUserWrapper(String id, String name, String apiKey,
+ long creationTimestamp, String about, String openId,
+ String fullName, String email, boolean isAdmin) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.apiKey = apiKey;
+ this.creationTimestamp = creationTimestamp;
+ this.about = about;
+ this.openId = openId;
+ this.fullName = fullName;
+ this.email = email;
+ this.isAdmin = isAdmin;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getApiKey() {
+ return apiKey;
+ }
+
+ public void setApiKey(String apiKey) {
+ this.apiKey = apiKey;
+ }
+
+ public long getCreationTimestamp() {
+ return creationTimestamp;
+ }
+
+ public void setCreationTimestamp(long creationTimestamp) {
+ this.creationTimestamp = creationTimestamp;
+ }
+
+ public String getAbout() {
+ return about;
+ }
+
+ public void setAbout(String about) {
+ this.about = about;
+ }
+
+ public String getOpenId() {
+ return openId;
+ }
+
+ public void setOpenId(String openId) {
+ this.openId = openId;
+ }
+
+ public String getFullName() {
+ return fullName;
+ }
+
+ public void setFullName(String fullName) {
+ this.fullName = fullName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public boolean isAdmin() {
+ return isAdmin;
+ }
+
+ public void setAdmin(boolean isAdmin) {
+ this.isAdmin = isAdmin;
+ }
+
+ @Override
+ public String toString() {
+ return "CKanUserExtended [id=" + id + ", name=" + name + ", apiKey=" + apiKey
+ + ", creationTimestamp=" + creationTimestamp + ", about="
+ + about + ", openId=" + openId + ", fullName=" + fullName
+ + ", email=" + email + ", isAdmin=" + isAdmin + "]";
+ }
+
+}
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/ROLES_IN_ORGANIZATION.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/ROLES_IN_ORGANIZATION.java
new file mode 100644
index 0000000..bda23be
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/ROLES_IN_ORGANIZATION.java
@@ -0,0 +1,11 @@
+package org.gcube.datacatalogue.ckanutillibrary.models;
+
+/**
+ * Roles that user can have into the group table
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ *
+ */
+public enum ROLES_IN_ORGANIZATION{
+ editor, admin, member
+}
\ No newline at end of file
diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/STATE.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/STATE.java
new file mode 100644
index 0000000..3a9c743
--- /dev/null
+++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/models/STATE.java
@@ -0,0 +1,10 @@
+package org.gcube.datacatalogue.ckanutillibrary.models;
+
+/**
+ * The current state of this group/user
+ * @author Costantino Perciante at ISTI-CNR
+ * (costantino.perciante@isti.cnr.it)
+ */
+public enum STATE{
+ deleted, active
+}
\ No newline at end of file
diff --git a/src/test/java/org/gcube/datacatalogue/ckanutillibrary/TestCKanLib.java b/src/test/java/org/gcube/datacatalogue/ckanutillibrary/TestCKanLib.java
new file mode 100644
index 0000000..d7fe512
--- /dev/null
+++ b/src/test/java/org/gcube/datacatalogue/ckanutillibrary/TestCKanLib.java
@@ -0,0 +1,92 @@
+package org.gcube.datacatalogue.ckanutillibrary;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.gcube.datacatalogue.ckanutillibrary.CKanUtilsFactory;
+import org.gcube.datacatalogue.ckanutillibrary.CKanUtilsImpl;
+import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
+import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.trentorise.opendata.jackan.model.CkanOrganization;
+
+public class TestCKanLib {
+
+ private static final Logger logger = LoggerFactory.getLogger(TestCKanLib.class);
+
+ CKanUtilsImpl instance;
+
+ //@Before
+ public void before() throws Exception{
+
+ instance = new CKanUtilsImpl("/gcube");
+
+ }
+
+ //@Test
+ public void testgetApiKeyFromUser() {
+
+ logger.debug("Testing getApiKeyFromUser");
+
+ String username = "francescomangiacrapa";
+ String key = instance.getApiKeyFromUser(username);
+
+ System.out.println("key for " + username + " is " + key);
+ }
+
+ //@Test
+ public void testgetUserFromApiKey() {
+
+ logger.debug("Testing getApiKeyFromUser");
+
+ String key = "put-your-key-here";
+ CKanUserWrapper user = instance.getUserFromApiKey(key);
+
+ System.out.println("user for " + key + " is " + user);
+ }
+
+ //@Test
+ public void getOrganizationsByUser() {
+
+ System.out.println("Testing getOrganizationsByUser");
+
+ String username = "francescomangiacrapa";
+ List organizations = instance.getOrganizationsByUser(username);
+
+ System.out.println("organizations for user " + username + " are: ");
+
+ for (CkanOrganization ckanOrganization : organizations) {
+ System.out.println("-" + ckanOrganization.getName());
+ }
+ }
+
+ //@Test
+ public void getGroupsAndRolesByUser() {
+
+ logger.debug("Testing getGroupsAndRolesByUser");
+
+ String username = "francescomangiacrapa";
+ List rolesToMatch = new ArrayList();
+ rolesToMatch.add(ROLES_IN_ORGANIZATION.admin);
+ rolesToMatch.add(ROLES_IN_ORGANIZATION.member);
+ rolesToMatch.add(ROLES_IN_ORGANIZATION.editor);
+ Map> map = instance.getGroupsAndRolesByUser(username, rolesToMatch);
+
+ System.out.println("organizations for user " + username + " are " + map);
+ }
+
+ //@Test
+ public void testFactory() throws Exception{
+
+ System.out.println("Creating factory object");
+ CKanUtilsImpl obj = CKanUtilsFactory.getInstance().getCkanUtilsForScope("/gcube");
+ System.out.println("Object created " + obj.getCatalogueUrl());
+
+
+ }
+
+}
diff --git a/target/profile.xml b/target/profile.xml
new file mode 100644
index 0000000..3d41792
--- /dev/null
+++ b/target/profile.xml
@@ -0,0 +1,25 @@
+
+
+
+ Service
+
+ Utility library to retrieve users information, organizations information and so on from the ckan d4science database.
+ DataAccess
+ ckan-util-library
+ 1.0.0-SNAPSHOT
+
+
+ ckan-util-library
+ 1.0.0-SNAPSHOT
+
+ org.gcube.data-catalogue
+ ckan-util-library
+ 1.0.0-SNAPSHOT
+
+
+ target/ckan-util-library-1.0.0-SNAPSHOT.jar
+
+
+
+
+