ckan-util-library/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanRunningCluster.java

256 lines
7.8 KiB
Java

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.encryption.StringEncrypter;
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 (for both its database and data catalogue url)
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class CKanRunningCluster {
//logger
private static final Logger logger = LoggerFactory.getLogger(CKanRunningCluster.class);
// database of the datacatalogue info
private final static String RUNTIME_DB_RESOURCE_NAME = "CKanDatabase";
private final static String PLATFORM_DB_NAME = "postgres";
// data catalogue info
private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue";
private final static String PLATFORM_CATALOGUE_NAME = "Tomcat";
// api key property
private final static String API_KEY_PROPERTY = "API_KEY";
// retrieved data
private List<String> datacatalogueUrls = new ArrayList<String>();
private List<String> hostsDB = new ArrayList<String>();
private List<Integer> portsDB = new ArrayList<Integer>();
private String nameDB;
private String userDB;
private String passwordDB;
// this token is needed in order to assign roles to user
private String sysAdminToken;
public CKanRunningCluster(String scope) throws Exception{
if(scope == null || scope.isEmpty())
throw new Exception("Invalid scope!!");
// retrieve the current scope and save it (it will be reset later)
String currentScope = ScopeProvider.instance.get();
logger.debug("Retrieving ckan database service end point information.");
try {
// set the scope
ScopeProvider.instance.set(scope);
List<ServiceEndpoint> resources = getConfigurationFromISFORDB();
if (resources.size() > 1) {
logger.error("Too many Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" in this scope");
throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name "
+ RUNTIME_DB_RESOURCE_NAME + " and Platform " + PLATFORM_DB_NAME + ". Only one allowed per infrasrtucture.");
}
else if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" and Platform " + PLATFORM_DB_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
hostsDB.add(accessPoint.address().split(":")[0]);
// save the port
int port = Integer.parseInt(accessPoint.address().split(":")[1]);
portsDB.add(port);
// save the name of the cluster (this should be unique)
nameDB = accessPoint.name();
// save user and password
passwordDB = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
userDB = accessPoint.username();
break;
}
}
}catch(Exception e ){
logger.error(e.toString());
throw new ServiceEndPointException();
}
}
logger.debug("Retrieving ckan data catalogue service end point information and sysadmin token.");
resources = getConfigurationFromISFORCatalogueUrl();
if (resources.size() > 1) {
logger.error("Too many Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" in this scope");
throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name "
+ RUNTIME_CATALOGUE_RESOURCE_NAME + " and Platform " + PLATFORM_CATALOGUE_NAME + ". Only one allowed per infrasrtucture.");
}
else if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" and Platform " + PLATFORM_CATALOGUE_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
datacatalogueUrls.add(accessPoint.address());
// retrieve sys admin token
sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value();
sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken);
break;
}
}
}catch(Exception e ){
logger.error(e.toString());
throw new ServiceEndPointException();
}
}
}catch(Exception e) {
logger.error(e.toString());
throw e;
}finally{
// set the scope back
ScopeProvider.instance.set(currentScope);
}
}
/**
* Retrieve endpoints information from IS for DB
* @return list of endpoints for ckan database
* @throws Exception
*/
private List<ServiceEndpoint> getConfigurationFromISFORDB() throws Exception{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_DB_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_DB_NAME +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
return toReturn;
}
/**
* Retrieve endpoints information from IS for DataCatalogue URL
* @return list of endpoints for ckan data catalogue
* @throws Exception
*/
private List<ServiceEndpoint> getConfigurationFromISFORCatalogueUrl() throws Exception{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_CATALOGUE_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_CATALOGUE_NAME +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
return toReturn;
}
/**
* Retrieve data catalogue url
*/
public List<String> getDataCatalogueUrl() {
return datacatalogueUrls;
}
/**
* Get the hosts for such resource.
* @return
*/
public List<String> getDatabaseHosts() {
return hostsDB;
}
/**
* Get the ports for such resource.
* @return
*/
public List<Integer> getDatabasePorts() {
return portsDB;
}
/**
* Get the database name.
* @return
*/
public String getDataBaseName() {
return nameDB;
}
/**
* Get the database's user.
* @return
*/
public String getDataBaseUser() {
return userDB;
}
/**
* Get the database's password.
* @return
*/
public String getDataBasePassword() {
return passwordDB;
}
/**
* @return the sysAdminToken
*/
public String getSysAdminToken() {
return sysAdminToken;
}
}