/* * Agiato: A simple no frill Cassandra API * Author: Pranab Ghosh * * Licensed under the Apache License, Version 2.0 (the "License"); you * may not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package agiato.cassandra.data; import agiato.cassandra.connect.Connector; import agiato.cassandra.connect.HostConnections; import agiato.cassandra.connect.LoadBalancer; import agiato.cassandra.meta.Cluster; import agiato.cassandra.meta.ColumnFamilyDef; import agiato.cassandra.meta.Host; import agiato.cassandra.meta.IndexDef; import agiato.cassandra.meta.MetaDataManager; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.cassandra.thrift.Cassandra; import org.apache.cassandra.thrift.CfDef; import org.apache.cassandra.thrift.KsDef; import org.apache.commons.pool.impl.GenericObjectPool; /** * * @author pranab */ public class DataManager { //private static GenericObjectPool connectionPool; private LoadBalancer loadBalancer; private static DataManager dataManager; /** * @param configFile * @param forceCreateKeySpace * @return * @throws Exception */ public static synchronized DataManager initialize(String configFile, boolean forceCreateKeySpace) throws Exception{ if (null == dataManager){ dataManager = new DataManager(configFile, forceCreateKeySpace); } return dataManager; } /** * @return */ public static DataManager instance(){ return dataManager; } /** * @param configFile * @param forceCreateKeySpace * @throws Exception */ public DataManager(String configFile, boolean forceCreateKeySpace) throws Exception{ MetaDataManager.initialize(configFile); MetaDataManager metaDatamanager = MetaDataManager.instance(); Cluster cluster = metaDatamanager.getCluster(); List<HostConnections> hostConnections = new ArrayList<HostConnections>(); for(Host host : cluster.getHosts()){ hostConnections.add(new HostConnections(host, cluster.getPoolConfig())); } //load balancer String loadBalancerClass = cluster.getLoadBalancerClass(); Class<? extends LoadBalancer> clazz = Class.forName(loadBalancerClass).asSubclass(LoadBalancer.class); loadBalancer = clazz.newInstance(); loadBalancer.setHostConnections(hostConnections); GenericObjectPool connectionPool = getConnectionPool(); Connector connector = (Connector)connectionPool.borrowObject(); Cassandra.Client client = connector.openConnection(); String keySpaceName = metaDatamanager.getKeySpace().getName(); try{ List<KsDef> ksDefs = client.describe_keyspaces(); boolean exists = false; for (KsDef ksDef : ksDefs){ if (ksDef.getName().equals(keySpaceName)){ exists = true; break; } } //drop existing key space if (exists && forceCreateKeySpace){ client.system_drop_keyspace(keySpaceName); exists = false; } //create keyspace if it does not exist if (!exists){ KsDef ks = new KsDef(); ks.setName(keySpaceName); ks.setReplication_factor(metaDatamanager.getKeySpace().getReplicationFactor()); ks.setStrategy_class(metaDatamanager.getKeySpace().getReplicaPlacementStrategy()); List<CfDef> cfDefs = new ArrayList<CfDef>(); for (ColumnFamilyDef colFam : metaDatamanager.getKeySpace().getColumnFamilies()) { CfDef cfDef = new CfDef(); cfDef.setKeyspace(metaDatamanager.getKeySpace().getName()); cfDef.setName(colFam.getName()); cfDef.setColumn_type(colFam.getColumnType()); cfDef.setComparator_type(colFam.getCompareWith()); if (colFam.isSuperColumn()){ cfDef.setSubcomparator_type(colFam.getCompareSubcolumnsWith()); } if(colFam.isKeysCachedSet()){ cfDef.setKey_cache_size(colFam.getKeysCached()); } if (colFam.isRowsCachedSet()){ cfDef.setRow_cache_size(colFam.getRowsCached()); } cfDefs.add(cfDef); } ks.setCf_defs(cfDefs); client.system_add_keyspace(ks); System.out.println("keyspace created : " + keySpaceName); } else { System.out.println("keyspace already exists : " + keySpaceName); } //create cf for indexes KsDef ksDef = client.describe_keyspace(keySpaceName); Set<String> colFamSet = new HashSet<String>(); if (null != metaDatamanager.getIndexes()) { for (IndexDef indexDef : metaDatamanager.getIndexes()){ String cfName = indexDef.getColFamilyName(); List<CfDef> cfDefs = ksDef.getCf_defs(); boolean cfExists = false; for (CfDef cfDef : cfDefs){ if (cfDef.getName().equals(cfName)) { cfExists = true; break; } } String colFamName = indexDef.getColFamilyName(); if (!cfExists && !colFamSet.contains(colFamName)){ CfDef cfDef = new CfDef(); cfDef.setKeyspace(keySpaceName); cfDef.setName(colFamName); boolean isSuperCol = indexDef.isCatIndexName(); cfDef.setColumn_type(isSuperCol? "Super" : "Standard"); cfDef.setComparator_type(indexDef.getIndexedDataType() == IndexDef.TYPE_STRING? "UTF8Type" : "LongType"); if (isSuperCol){ cfDef.setSubcomparator_type(indexDef.getStoredDataType() == IndexDef.TYPE_STRING? "UTF8Type" : "LongType"); } cfDef.setKey_cache_size(indexDef.getIndexKeysCached()); cfDef.setRow_cache_size(indexDef.getIndexRowsCached()); client.system_add_column_family(cfDef); colFamSet.add(colFamName); } } } //asociate key space loadBalancer.associateKeySpace(keySpaceName); } finally { client.set_keyspace(keySpaceName); returnConnection(connector); } } /** * @return * @throws Exception */ public Connector borrowConnection() throws Exception{ HostConnections hostConns = loadBalancer.select(); return (Connector)hostConns.getConnectionPool().borrowObject(); } /** * @param connectionPool * @return * @throws Exception */ public Connector borrowConnection(GenericObjectPool connectionPool) throws Exception{ return (Connector)connectionPool.borrowObject(); } /** * @param connectionPool * @param connector * @throws Exception */ public void returnConnection(GenericObjectPool connectionPool, Connector connector) throws Exception{ connectionPool.returnObject(connector); } /** * @param connector * @throws Exception */ public void returnConnection(Connector connector) throws Exception{ GenericObjectPool connectionPool = loadBalancer.findConnectionPool(connector.getHost()); connectionPool.returnObject(connector); } /** * @return */ public GenericObjectPool getConnectionPool(){ return loadBalancer.select().getConnectionPool(); } }