First import

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/ckan-util-library@129006 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-06-07 14:00:05 +00:00
parent 00d2a2dcd2
commit 2e63bc3455
26 changed files with 1385 additions and 0 deletions

27
.classpath Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

36
.project Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ckan-util-library</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -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

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="ckan-util-library">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
</wb-module>
</project-modules>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.7"/>
<installed facet="jst.utility" version="1.0"/>
</faceted-project>

View File

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

1
distro/LICENSE Normal file
View File

@ -0,0 +1 @@
${gcube.license}

62
distro/README Normal file
View File

@ -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.

5
distro/changelog.xml Normal file
View File

@ -0,0 +1,5 @@
<ReleaseNotes>
<Changeset component="org.gcube.dataaccess.ckan-util-library.1-0-0" date="2016-06-01">
<Change>First Release</Change>
</Changeset>
</ReleaseNotes>

31
distro/descriptor.xml Normal file
View File

@ -0,0 +1,31 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>servicearchive</id>
<formats>
<format>tar.gz</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<directory>${distroDirectory}</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include>README</include>
<include>LICENSE</include>
<include>changelog.xml</include>
<include>profile.xml</include>
</includes>
<fileMode>755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
<files>
<file>
<source>target/${build.finalName}.${project.packaging}</source>
<outputDirectory>/${artifactId}</outputDirectory>
</file>
</files>
</assembly>

25
distro/profile.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ID></ID>
<Type>Service</Type>
<Profile>
<Description>${Description}</Description>
<Class>DataAccess</Class>
<Name>${artifactId}</Name>
<Version>${version}</Version>
<Packages>
<Software>
<Name>${artifactId}</Name>
<Version>${version}</Version>
<MavenCoordinates>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
</MavenCoordinates>
<Files>
<File>target/${build.finalName}.jar</File>
</Files>
</Software>
</Packages>
</Profile>
</Resource>

187
pom.xml Normal file
View File

@ -0,0 +1,187 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.gcube.tools</groupId>
<version>1.0.0</version>
<relativePath />
</parent>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>ckan-util-library</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>CKan utility library</name>
<description>
Utility library to retrieve users information, organizations information and so on from the ckan d4science database.
</description>
<properties>
<distroDirectory>distro</distroDirectory>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<jackanVersion>0.4.2</jackanVersion>
<postgresVersion>9.4.1208.jre7</postgresVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>LATEST</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresVersion}</version>
</dependency>
<!-- CKAN client library -->
<dependency>
<groupId>eu.trentorise.opendata</groupId>
<artifactId>jackan</artifactId>
<version>${jackanVersion}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.gcube.common.portal</groupId>
<artifactId>portal-manager</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.resources.discovery</groupId>
<artifactId>ic-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-encryption</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope-maps</artifactId>
<scope>provided</scope>
<!-- put at provided for deploying -->
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-profile</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target</outputDirectory>
<resources>
<resource>
<directory>${distroDirectory}</directory>
<filtering>true</filtering>
<includes>
<include>profile.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptors>
<descriptor>${distroDirectory}/descriptor.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<!-- <descriptorRefs> -->
<!-- <descriptorRef>jar-with-dependencies</descriptorRef> -->
<!-- </descriptorRefs> -->
</configuration>
<executions>
<execution>
<id>servicearchive</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -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<String> hosts = new ArrayList<String>();
private List<Integer> ports = new ArrayList<Integer>();
private String dbName;
private String dbUser;
private String dbPassword;
public CKanRunningCluster(String infrastructure) throws Exception{
try {
List<ServiceEndpoint> 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<AccessPoint> 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<ServiceEndpoint> 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<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
ScopeProvider.instance.set(currScope);
return toReturn;
}
/**
* Get the hosts for such resource.
* @return
*/
public List<String> getHosts() {
return hosts;
}
/**
* Get the ports for such resource.
* @return
*/
public List<Integer> 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;
}
}

View File

@ -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 <scope, util class for this scope>
*/
private static Map<String, CKanUtilsImpl> instanceForScopes;
/**
* this object singleton instance
*/
private static CKanUtilsFactory factoryInstance = new CKanUtilsFactory();
/**
* private constructor
*/
private CKanUtilsFactory(){
logger.debug("Instanciating factory");
instanceForScopes = new HashMap<String, CKanUtilsImpl>();
}
/**
* 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;
}
}
}
}

View File

@ -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<CkanOrganization> getOrganizationsByUser(String username) {
logger.debug("Requested organizations for user " + username);
List<String> organizationIds = getOrganizationsIds();
String userId = getUserIdByUsername(username);
// list to return
List<CkanOrganization> toReturn = new ArrayList<CkanOrganization>();
// 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<String, List<ROLES_IN_ORGANIZATION>> getGroupsAndRolesByUser(
String username, List<ROLES_IN_ORGANIZATION> rolesToMatch) {
logger.debug("Requested roles the user " + username + " has into its organizations");
logger.debug("Roles to check are " + rolesToMatch);
Map<String, List<ROLES_IN_ORGANIZATION>> toReturn = new HashMap<String, List<ROLES_IN_ORGANIZATION>>();
try{
// get id from the user
String userId = getUserIdByUsername(username);
// use the above method to require the list of user's organizations
List<CkanOrganization> 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<ROLES_IN_ORGANIZATION> rolesIntoOrg = new ArrayList<ROLES_IN_ORGANIZATION>();
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<String> getOrganizationsIds(){
logger.debug("Request organization ids");
List<String> toReturn = new ArrayList<String>();
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<String> getOrganizationsNamesByUser(String username) {
List<CkanOrganization> orgs = getOrganizationsByUser(username);
List<String> orgsName = new ArrayList<String>();
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<CkanLicense> licenses = client.getLicenseList();
for (CkanLicense ckanLicense : licenses) {
if(ckanLicense.getTitle().equals(chosenLicense))
return ckanLicense.getId();
}
return null;
}
@Override
public List<String> getLicenseTitles() {
logger.info("Request for CKAN licenses");
// get the url and the api key of the user
String ckanPortalUrl = getCatalogueUrl();
List<String> result = new ArrayList<String>();
CkanClient client = new CkanClient(ckanPortalUrl);
//retrieve the list of available licenses
List<CkanLicense> licenses = client.getLicenseList();
for (CkanLicense ckanLicense : licenses) {
result.add(ckanLicense.getTitle());
logger.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId());
}
return result;
}
}

View File

@ -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<CkanOrganization> getOrganizationsByUser(String username);
/**
* Returns the list of organizations' names to whom the user belongs.
* @param username
* @return a list of organizations
*/
public List<String> 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<String, List<ROLES_IN_ORGANIZATION>> getGroupsAndRolesByUser(String username, List<ROLES_IN_ORGANIZATION> rolesToMatch);
/**
* Return the ckan catalogue url in this scope.
* @return
*/
public String getCatalogueUrl();
/**
* Get the list of licenses' titles.
* @return
*/
public List<String> getLicenseTitles();
/**
* Finds the id associated to the chosen license
* @param chosenLicense
* @return
*/
public String findLicenseIdByLicense(String chosenLicense);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 + "]";
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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<CkanOrganization> 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<ROLES_IN_ORGANIZATION> rolesToMatch = new ArrayList<ROLES_IN_ORGANIZATION>();
rolesToMatch.add(ROLES_IN_ORGANIZATION.admin);
rolesToMatch.add(ROLES_IN_ORGANIZATION.member);
rolesToMatch.add(ROLES_IN_ORGANIZATION.editor);
Map<String, List<ROLES_IN_ORGANIZATION>> 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());
}
}

25
target/profile.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ID></ID>
<Type>Service</Type>
<Profile>
<Description>Utility library to retrieve users information, organizations information and so on from the ckan d4science database.</Description>
<Class>DataAccess</Class>
<Name>ckan-util-library</Name>
<Version>1.0.0-SNAPSHOT</Version>
<Packages>
<Software>
<Name>ckan-util-library</Name>
<Version>1.0.0-SNAPSHOT</Version>
<MavenCoordinates>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>ckan-util-library</artifactId>
<version>1.0.0-SNAPSHOT</version>
</MavenCoordinates>
<Files>
<File>target/ckan-util-library-1.0.0-SNAPSHOT.jar</File>
</Files>
</Software>
</Packages>
</Profile>
</Resource>