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