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 (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); //properties private final static String RUNTIME_DB_RESOURCE_NAME = "CKanDatabase"; private final static String PLATFORM_DB_NAME = "postgres"; private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue"; private final static String PLATFORM_CATALOGUE_NAME = "Tomcat"; // retrieved data private List datacatalogueUrls = new ArrayList(); private List hostsDB = new ArrayList(); private List portsDB = new ArrayList(); private String nameDB; private String userDB; private String passwordDB; public CKanRunningCluster(String scope) throws Exception{ logger.debug("Retrieving ckan database service end point information."); try { List resources = getConfigurationFromISFORDB(scope); 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 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 = accessPoint.password(); userDB = accessPoint.username(); break; } } }catch(Exception e ){ logger.error(e.toString()); throw new ServiceEndPointException(); } } } catch (Exception e) { logger.error(e.toString()); throw e; } logger.debug("Retrieving ckan data catalogue service end point information."); try { List resources = getConfigurationFromISFORCatalogueUrl(scope); 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 accessPointIterator = res.profile().accessPoints().iterator(); while (accessPointIterator.hasNext()) { ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator .next(); // add this host datacatalogueUrls.add(accessPoint.address()); 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 for DB * @return list of endpoints for ckan database * @throws Exception */ private List getConfigurationFromISFORDB(String scope) throws Exception{ String evaluatedScope = ""; if(scope != null && !scope.isEmpty()) evaluatedScope += scope; else{ PortalContext context = PortalContext.getConfiguration(); evaluatedScope += context.getInfrastructureName(); } String currScope = ScopeProvider.instance.get(); ScopeProvider.instance.set(evaluatedScope); 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 client = clientFor(ServiceEndpoint.class); List toReturn = client.submit(query); ScopeProvider.instance.set(currScope); return toReturn; } /** * Retrieve endpoints information from IS for DataCatalogue URL * @return list of endpoints for ckan data catalogue * @throws Exception */ private List getConfigurationFromISFORCatalogueUrl(String scope) throws Exception{ String evaluatedScope = ""; if(scope != null && !scope.isEmpty()) evaluatedScope += scope; else{ PortalContext context = PortalContext.getConfiguration(); evaluatedScope += context.getInfrastructureName(); } String currScope = ScopeProvider.instance.get(); ScopeProvider.instance.set(evaluatedScope); 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 client = clientFor(ServiceEndpoint.class); List toReturn = client.submit(query); ScopeProvider.instance.set(currScope); return toReturn; } /** * Retrieve data catalogue url */ public List getDataCatalogueUrl() { return datacatalogueUrls; } /** * Get the hosts for such resource. * @return */ public List getDatabaseHosts() { return hostsDB; } /** * Get the ports for such resource. * @return */ public List 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; } }