Package com.impetus.client.cassandra.pelops

Source Code of com.impetus.client.cassandra.pelops.PelopsClient

/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
*  *
*  * 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 com.impetus.client.cassandra.pelops;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.PersistenceException;
import javax.persistence.metamodel.EntityType;

import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnParent;
import org.apache.cassandra.thrift.CounterColumn;
import org.apache.cassandra.thrift.CounterSuperColumn;
import org.apache.cassandra.thrift.IndexClause;
import org.apache.cassandra.thrift.IndexExpression;
import org.apache.cassandra.thrift.IndexOperator;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.KeyRange;
import org.apache.cassandra.thrift.KeySlice;
import org.apache.cassandra.thrift.SlicePredicate;
import org.apache.cassandra.thrift.SuperColumn;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.thrift.TException;
import org.scale7.cassandra.pelops.Bytes;
import org.scale7.cassandra.pelops.Mutator;
import org.scale7.cassandra.pelops.RowDeletor;
import org.scale7.cassandra.pelops.Selector;
import org.scale7.cassandra.pelops.exceptions.PelopsException;
import org.scale7.cassandra.pelops.pool.IThriftPool;
import org.scale7.cassandra.pelops.pool.IThriftPool.IPooledConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.impetus.client.cassandra.CassandraClientBase;
import com.impetus.client.cassandra.common.CassandraConstants;
import com.impetus.client.cassandra.common.CassandraUtilities;
import com.impetus.client.cassandra.datahandler.CassandraDataHandler;
import com.impetus.client.cassandra.index.InvertedIndexHandler;
import com.impetus.client.cassandra.query.CassQuery;
import com.impetus.client.cassandra.thrift.ThriftRow;
import com.impetus.kundera.Constants;
import com.impetus.kundera.KunderaException;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.EnhanceEntity;
import com.impetus.kundera.db.RelationHolder;
import com.impetus.kundera.db.SearchResult;
import com.impetus.kundera.generator.AutoGenerator;
import com.impetus.kundera.generator.TableGenerator;
import com.impetus.kundera.graph.Node;
import com.impetus.kundera.index.IndexManager;
import com.impetus.kundera.metadata.KunderaMetadataManager;
import com.impetus.kundera.metadata.MetadataUtils;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.MetamodelImpl;
import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor;
import com.impetus.kundera.metadata.model.annotation.DefaultEntityAnnotationProcessor;
import com.impetus.kundera.metadata.model.type.AbstractManagedType;
import com.impetus.kundera.persistence.EntityManagerFactoryImpl.KunderaMetadata;
import com.impetus.kundera.persistence.EntityReader;
import com.impetus.kundera.persistence.api.Batcher;
import com.impetus.kundera.persistence.context.jointable.JoinTableData;
import com.impetus.kundera.property.PropertyAccessor;
import com.impetus.kundera.property.PropertyAccessorFactory;
import com.impetus.kundera.property.PropertyAccessorHelper;
import com.impetus.kundera.utils.KunderaCoreUtils;
import com.impetus.kundera.utils.TimestampGenerator;

/**
* Client implementation using Pelops. http://code.google.com/p/pelops/
*
* @author animesh.kumar
* @since 0.1
*/
public class PelopsClient extends CassandraClientBase implements Client<CassQuery>, Batcher, TableGenerator,
        AutoGenerator
{
    /** log for this class. */
    private static Logger log = LoggerFactory.getLogger(PelopsClient.class);

    /** The data handler. */
    private PelopsDataHandler dataHandler;

    /** Handler for Inverted indexing */
    private InvertedIndexHandler invertedIndexHandler;

    /** The reader. */
    private EntityReader reader;

    private PelopsClientFactory clientFactory;

    private IThriftPool pool;

    /**
     * default constructor.
     *
     * @param indexManager
     *            the index manager
     * @param reader
     *            the reader
     * @param persistenceUnit
     *            the persistence unit
     */
    public PelopsClient(IndexManager indexManager, EntityReader reader, PelopsClientFactory clientFactory,
            String persistenceUnit, Map<String, Object> externalProperties, IThriftPool pool,
            final KunderaMetadata kunderaMetadata, final TimestampGenerator generator)
    {
        super(persistenceUnit, externalProperties, kunderaMetadata, generator);
        this.indexManager = indexManager;
        this.dataHandler = new PelopsDataHandler(this, kunderaMetadata, generator);
        this.reader = reader;
        this.clientFactory = clientFactory;
        this.clientMetadata = clientFactory.getClientMetadata();
        this.invertedIndexHandler = new PelopsInvertedIndexHandler(this,
                MetadataUtils.useSecondryIndex(this.clientMetadata), generator);
        this.pool = pool;
    }

    @Override
    public final Object find(Class entityClass, Object rowId)
    {
        return super.find(entityClass, rowId);
    }

    @Override
    public final <E> List<E> findAll(Class<E> entityClass, String[] columnsToSelect, Object... rowIds)
    {
        return super.findAll(entityClass, columnsToSelect, rowIds);
    }

    /**
     * Method to return list of entities for given below attributes:.
     *
     * @param entityClass
     *            entity class
     * @param relationNames
     *            relation names
     * @param isWrapReq
     *            true, in case it needs to populate enhance entity.
     * @param metadata
     *            entity metadata.
     * @param rowIds
     *            array of row key s
     * @return list of wrapped entities.
     */
    @Override
    public final List find(Class entityClass, List<String> relationNames, boolean isWrapReq, EntityMetadata metadata,
            Object... rowIds)
    {
        if (!isOpen())
        {
            throw new PersistenceException("PelopsClient is closed.");
        }

        return findByRowKeys(entityClass, relationNames, isWrapReq, metadata, rowIds);
    }

    @Override
    public void delete(Object entity, Object pKey)
    {
        if (!isOpen())
        {
            throw new PersistenceException("PelopsClient is closed.");
        }
        EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entity.getClass());

        MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                metadata.getPersistenceUnit());
        AbstractManagedType managedType = (AbstractManagedType) metaModel.entity(metadata.getEntityClazz());
        // For secondary tables.
        List<String> secondaryTables = ((DefaultEntityAnnotationProcessor) managedType.getEntityAnnotation())
                .getSecondaryTablesName();
        secondaryTables.add(metadata.getTableName());

        for (String tableName : secondaryTables)
        {
            if (isCql3Enabled(metadata))
            {
                String deleteQuery = onDeleteQuery(metadata, tableName, metaModel, pKey);
                executeCQLQuery(deleteQuery, isCql3Enabled(metadata));
            }
            else
            {
                if (metadata.isCounterColumnType())
                {
                    deleteRecordFromCounterColumnFamily(pKey, tableName, metadata, getConsistencyLevel());
                }
                else
                {
                    RowDeletor rowDeletor = clientFactory.getRowDeletor(pool);
                    rowDeletor.deleteRow(tableName, Bytes.fromByteBuffer(CassandraUtilities.toBytes(pKey, metadata
                            .getIdAttribute().getJavaType())), getConsistencyLevel());

                }
            }
        }
        getIndexManager().remove(metadata, entity, pKey);

        // Delete from Inverted Index if applicable
        Object conn = getConnection();
        try
        {
            invertedIndexHandler.delete(entity, metadata, getConsistencyLevel(), kunderaMetadata);
        }
        finally
        {
            if (conn != null)
            {
                releaseConnection(conn);
            }
        }
    }

    @Override
    public final void close()
    {
        this.indexManager.flush();
        this.dataHandler = null;
        this.invertedIndexHandler = null;
    }

    /**
     * Persists records into Join Table
     */
    public void persistJoinTable(JoinTableData joinTableData)
    {
        Mutator mutator = clientFactory.getMutator(pool);

        String joinTableName = joinTableData.getJoinTableName();
        String invJoinColumnName = joinTableData.getInverseJoinColumnName();
        Map<Object, Set<Object>> joinTableRecords = joinTableData.getJoinTableRecords();
        EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata,
                joinTableData.getEntityClass());

        if (isCql3Enabled(entityMetadata))
        {
            Cassandra.Client conn = null;
            Object pooledConnection = null;
            pooledConnection = getConnection();
            conn = (org.apache.cassandra.thrift.Cassandra.Client) getConnection(pooledConnection);
            persistJoinTableByCql(joinTableData, conn);
        }
        else
        {
            for (Object key : joinTableRecords.keySet())
            {
                Set<Object> values = joinTableRecords.get(key);

                List<Column> columns = new ArrayList<Column>();

                Class columnType = null;
                for (Object value : values)
                {
                    Column column = new Column();
                    column.setName(PropertyAccessorFactory.STRING.toBytes(invJoinColumnName
                            + Constants.JOIN_COLUMN_NAME_SEPARATOR + value.toString()));
                    column.setValue(PropertyAccessorHelper.getBytes(value));
                    column.setTimestamp(generator.getTimestamp());
                    columnType = value.getClass();
                    columns.add(column);
                }

                createIndexesOnColumns(entityMetadata, joinTableName, columns, columnType);

                mutator.writeColumns(joinTableName, Bytes.fromByteArray(PropertyAccessorHelper.getBytes(key)),
                        Arrays.asList(columns.toArray(new Column[0])));
            }
        }
        if (log.isInfoEnabled())
        {
            log.info(" Persisted data with join table column family {}", joinTableData.getJoinTableName());
        }
        mutator.execute(getConsistencyLevel());
    }

    @Override
    public <E> List<E> getColumnsById(String schemaName, String joinTableName, String joinColumnName,
            String inverseJoinColumnName, Object parentId, Class columnJavaType)
    {
        List<Object> foreignKeys = new ArrayList<Object>();

        if (getCqlVersion().equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0))
        {
            foreignKeys = getColumnsByIdUsingCql(schemaName, joinTableName, joinColumnName, inverseJoinColumnName,
                    parentId, columnJavaType);
        }
        else
        {
            Selector selector = clientFactory.getSelector(pool);

            List<Column> columns = selector.getColumnsFromRow(joinTableName,
                    Bytes.fromByteArray(PropertyAccessorHelper.getBytes(parentId)),
                    Selector.newColumnsPredicateAll(true, 10), getConsistencyLevel());

            foreignKeys = dataHandler.getForeignKeysFromJoinTable(inverseJoinColumnName, columns, columnJavaType);

            if (log.isInfoEnabled())
            {
                log.info("Returning number of keys from join table", foreignKeys != null ? foreignKeys.size() : null);
            }
        }
        return (List<E>) foreignKeys;
    }

    @Override
    public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName,
            Object columnValue, Class entityClazz)
    {
        List<Object> rowKeys = new ArrayList<Object>();

        if (getCqlVersion().equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0))
        {
            rowKeys = findIdsByColumnUsingCql(schemaName, tableName, pKeyName, columnName, columnValue, entityClazz);
        }
        else
        {
            Selector selector = clientFactory.getSelector(pool);
            SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, 10000);
            EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClazz);

            IndexClause ix = Selector.newIndexClause(Bytes.EMPTY, 10000, Selector.newIndexExpression(columnName
                    + Constants.JOIN_COLUMN_NAME_SEPARATOR + columnValue, IndexOperator.EQ,
                    Bytes.fromByteArray(PropertyAccessorHelper.getBytes(columnValue))));

            Map<Bytes, List<Column>> qResults = selector.getIndexedColumns(tableName, ix, slicePredicate,
                    getConsistencyLevel());

            // iterate through complete map and
            Iterator<Bytes> rowIter = qResults.keySet().iterator();
            while (rowIter.hasNext())
            {
                Bytes rowKey = rowIter.next();

                PropertyAccessor<?> accessor = PropertyAccessorFactory.getPropertyAccessor((Field) metadata
                        .getIdAttribute().getJavaMember());
                Object value = accessor.fromBytes(metadata.getIdAttribute().getJavaType(), rowKey.toByteArray());

                rowKeys.add(value);
            }
        }
        if (rowKeys != null && !rowKeys.isEmpty())
        {
            return rowKeys.toArray(new Object[0]);
        }

        if (log.isInfoEnabled())
        {
            log.info("No row keys found, returning null.");
        }
        return null;
    }

    @Override
    public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue)
    {

        if (!isOpen())
        {
            throw new PersistenceException("PelopsClient is closed.");
        }

        RowDeletor rowDeletor = clientFactory.getRowDeletor(pool);
        rowDeletor.deleteRow(tableName,
                Bytes.fromByteBuffer(CassandraUtilities.toBytes(columnValue, columnValue.getClass())),
                getConsistencyLevel());

    }

    @Override
    public <E> List<E> find(Class<E> entityClass, Map<String, String> embeddedColumnMap)
    {
        return super.find(entityClass, embeddedColumnMap, dataHandler);
    }

    /*
     * (non-Javadoc)
     *
     * @see com.impetus.kundera.client.Client#find(java.lang.String,
     * java.lang.String, com.impetus.kundera.metadata.model.EntityMetadata)
     */
    @Override
    public List<Object> findByRelation(String colName, Object colValue, Class clazz)
    {
        EntityMetadata m = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, clazz);
        List<Object> entities = null;
        if (isCql3Enabled(m))
        {
            entities = findByRelationQuery(m, colName, colValue, clazz, dataHandler);
        }
        else
        {
            Selector selector = clientFactory.getSelector(pool);
            SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, 10000);
            IndexClause ix = Selector.newIndexClause(
                    Bytes.EMPTY,
                    10000,
                    Selector.newIndexExpression(colName, IndexOperator.EQ,
                            Bytes.fromByteArray(PropertyAccessorHelper.getBytes(colValue))));
            Map<Bytes, List<Column>> qResults;
            try
            {
                qResults = selector.getIndexedColumns(m.getTableName(), ix, slicePredicate, getConsistencyLevel());
            }
            catch (PelopsException e)
            {
                log.warn("Error while retrieving entities for given column {} for class {}.", colName, clazz);
                return entities;
            }
            entities = new ArrayList<Object>(qResults.size());
            // iterate through complete map and populateData
            MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                    m.getPersistenceUnit());

            EntityType entityType = metaModel.entity(m.getEntityClazz());

            List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();

            if (subManagedType.isEmpty())
            {
                entities = populateData(m, qResults, entities, false, m.getRelationNames(), dataHandler);
            }
            else
            {
                for (AbstractManagedType subEntity : subManagedType)
                {
                    EntityMetadata subEntityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata,
                            subEntity.getJavaType());
                    entities = populateData(subEntityMetadata, qResults, entities, false,
                            subEntityMetadata.getRelationNames(), dataHandler);
                }
            }

        }
        return entities;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.impetus.kundera.client.Client#getReader()
     */
    @Override
    public EntityReader getReader()
    {
        return reader;
    }

    @Override
    public Class<CassQuery> getQueryImplementor()
    {
        return CassQuery.class;
    }

    @Override
    protected void onPersist(EntityMetadata metadata, Object entity, Object id, List<RelationHolder> rlHolders)
    {

        if (!isOpen())
        {
            throw new PersistenceException("PelopsClient is closed.");
        }

        // check for counter column
        if (isUpdate && metadata.isCounterColumnType())
        {
            throw new UnsupportedOperationException("Invalid operation! Merge is not possible over counter column.");
        }

        String insert_Query = null;
        if (isCql3Enabled(metadata))
        {
            Cassandra.Client client = getRawClient(metadata.getSchema());
            try
            {
                cqlClient.persist(metadata, entity, client, rlHolders, getTtlValues().get(metadata.getTableName()));
            }
            catch (InvalidRequestException e)
            {
                log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e);
                throw new KunderaException(e);
            }
            catch (TException e)
            {
                log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e);
                throw new KunderaException(e);
            }
            catch (UnsupportedEncodingException e)
            {
                log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e);
                throw new KunderaException(e);
            }
        }
        else
        {
            Collection<ThriftRow> tfRows = null;
            try
            {
                String columnFamily = metadata.getTableName();
                tfRows = dataHandler.toThriftRow(entity, id, metadata, columnFamily, getTtlValues().get(columnFamily));
            }
            catch (Exception e)
            {
                log.error("Error during persist, Caused by: .", e);
                throw new KunderaException(e);
            }
            for (ThriftRow tf : tfRows)
            {

                if (tf.getColumnFamilyName().equals(metadata.getTableName()))
                {
                    addRelationsToThriftRow(metadata, tf, rlHolders);
                }
                Mutator mutator = clientFactory.getMutator(pool);
                if (metadata.isCounterColumnType())
                {
                    if (log.isInfoEnabled())
                    {
                        log.info("Persisting counter column family record for row key {}", tf.getId());
                    }
                    List<CounterColumn> thriftCounterColumns = tf.getCounterColumns();
                    List<CounterSuperColumn> thriftCounterSuperColumns = tf.getCounterSuperColumns();
                    if (thriftCounterColumns != null && !thriftCounterColumns.isEmpty())
                    {
                        mutator.writeCounterColumns(tf.getColumnFamilyName(),
                                Bytes.fromByteBuffer(CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass())),
                                Arrays.asList(tf.getCounterColumns().toArray(new CounterColumn[0])));
                    }

                    if (thriftCounterSuperColumns != null && !thriftCounterSuperColumns.isEmpty())
                    {
                        for (CounterSuperColumn sc : thriftCounterSuperColumns)
                        {
                            mutator.writeSubCounterColumns(
                                    tf.getColumnFamilyName(),
                                    Bytes.fromByteBuffer(CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass())),
                                    Bytes.fromByteArray(sc.getName()), sc.getColumns());
                        }
                    }
                }
                else
                {
                    List<Column> thriftColumns = tf.getColumns();
                    List<SuperColumn> thriftSuperColumns = tf.getSuperColumns();
                    if (thriftColumns != null && !thriftColumns.isEmpty())
                    {
                        // Bytes.from
                        mutator.writeColumns(tf.getColumnFamilyName(),
                                Bytes.fromByteBuffer(CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass())),
                                tf.getColumns());
                    }

                    if (thriftSuperColumns != null && !thriftSuperColumns.isEmpty())
                    {
                        for (SuperColumn sc : thriftSuperColumns)
                        {
                            if (log.isInfoEnabled())
                            {
                                log.info("Persisting super column family record for row key {}", tf.getId());
                            }

                            mutator.writeSubColumns(
                                    tf.getColumnFamilyName(),
                                    Bytes.fromByteBuffer(CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass())),
                                    Bytes.fromByteArray(sc.getName()), sc.getColumns());
                        }
                    }
                }
                mutator.execute(getConsistencyLevel());
            }
            tfRows = null;
            if (isTtlPerRequest())
            {
                getTtlValues().clear();
            }
        }
    }

    /**
     * Indexes @Embedded and @ElementCollection objects of this entity to a
     * separate column family
     */
    @Override
    protected void indexNode(Node node, EntityMetadata entityMetadata)
    {
        // Index to lucene if applicable
        super.indexNode(node, entityMetadata);

        // Write to inverted index table if applicable
        // Delete from Inverted Index if applicable
        invertedIndexHandler.write(node, entityMetadata, getPersistenceUnit(), getConsistencyLevel(), dataHandler);
    }

    /**
     * Load super columns.
     *
     * @param keyspace
     *            the keyspace
     * @param columnFamily
     *            the column family
     * @param rowId
     *            the row id
     * @param superColumnNames
     *            the super column names
     * @return the list
     */

    @Override
    public final List<SuperColumn> loadSuperColumns(String keyspace, String columnFamily, String rowId,
            String... superColumnNames)
    {
        if (!isOpen())
            throw new PersistenceException("PelopsClient is closed.");
        Selector selector = clientFactory.getSelector(pool);
        List<ByteBuffer> rowKeys = new ArrayList<ByteBuffer>();
        rowKeys.add(ByteBuffer.wrap(rowId.getBytes()));

        if (log.isInfoEnabled())
        {
            log.info("Retrieving record of super column family {} for row key {}", columnFamily, rowId);
        }

        return selector.getSuperColumnsFromRow(columnFamily, rowId, Selector.newColumnsPredicate(superColumnNames),
                getConsistencyLevel());
    }

    /** Query related methods */

    /**
     * Method to execute cql query and return back entity/enhance entities.
     *
     * @param cqlQuery
     *            cql query to be executed.
     * @param clazz
     *            entity class.
     * @param relationalField
     *            collection for relational fields.
     * @return list of objects.
     *
     */
    @Override
    public List executeQuery(Class clazz, List<String> relationalField, boolean isNative, String cqlQuery)
    {
        return super.executeSelectQuery(clazz, relationalField, dataHandler, isNative, cqlQuery);
    }

    /**
     * Find.
     *
     * @param ixClause
     *            the ix clause
     * @param m
     *            the m
     * @param isRelation
     *            the is relation
     * @param relations
     *            the relations
     * @return the list
     */
    @Override
    public List find(List<IndexClause> ixClause, EntityMetadata m, boolean isRelation, List<String> relations,
            int maxResult, List<String> columns)
    {
        Selector selector = clientFactory.getSelector(pool);

        SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, Integer.MAX_VALUE);
        if (columns != null && !columns.isEmpty())
        {
            slicePredicate = Selector.newColumnsPredicate(columns.toArray(new String[] {}));
        }

        List<Object> entities = new ArrayList<Object>();
        if (ixClause.isEmpty())
        {
            if (m.isCounterColumnType())
            {
                try
                {
                    IPooledConnection connection = getConnection();
                    org.apache.cassandra.thrift.Cassandra.Client thriftClient = connection.getAPI();
                    List<KeySlice> ks = thriftClient.get_range_slices(new ColumnParent(m.getTableName()),
                            slicePredicate, Selector.newKeyRange("", "", maxResult), getConsistencyLevel());
                    connection.release();
                    entities = onCounterColumn(m, isRelation, relations, ks);
                }
                catch (InvalidRequestException irex)
                {
                    log.error("Error during executing find, Caused by: .", irex);
                    throw new PersistenceException(irex);
                }
                catch (UnavailableException uex)
                {
                    log.error("Error during executing find, Caused by: .", uex);
                    throw new PersistenceException(uex);
                }
                catch (TimedOutException tex)
                {
                    log.error("Error during executing find, Caused by: .", tex);
                    throw new PersistenceException(tex);
                }
                catch (TException tex)
                {
                    log.error("Error during executing find, Caused by: .", tex);
                    throw new PersistenceException(tex);
                }
            }
            else
            {
                if (m.getType().isSuperColumnFamilyMetadata())
                {
                    Map<Bytes, List<SuperColumn>> qResults = selector.getSuperColumnsFromRows(m.getTableName(),
                            selector.newKeyRange("", "", maxResult), slicePredicate, getConsistencyLevel());
                    entities = new ArrayList<Object>(qResults.size());

                    MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                            m.getPersistenceUnit());

                    EntityType entityType = metaModel.entity(m.getEntityClazz());

                    List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();

                    for (Bytes key : qResults.keySet())
                    {
                        onSuperColumn(m, isRelation, relations, entities, qResults.get(key), key.getBytes());
                    }
                }
                else
                {
                    Map<Bytes, List<Column>> qResults = selector.getColumnsFromRows(m.getTableName(),
                            selector.newKeyRange("", "", maxResult), slicePredicate, getConsistencyLevel());
                    entities = new ArrayList<Object>(qResults.size());
                    MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                            m.getPersistenceUnit());

                    EntityType entityType = metaModel.entity(m.getEntityClazz());

                    List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();
                    for (Bytes key : qResults.keySet())
                    {
                        onColumn(m, isRelation, relations, entities, qResults.get(key), subManagedType, key.getBytes());
                    }
                }

            }
        }
        else
        {
            entities = new ArrayList<Object>();
            for (IndexClause ix : ixClause)
            {
                Map<Bytes, List<Column>> qResults = selector.getIndexedColumns(m.getTableName(), ix, slicePredicate,
                        getConsistencyLevel());

                MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                        m.getPersistenceUnit());

                EntityType entityType = metaModel.entity(m.getEntityClazz());

                List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();

                for (Bytes key : qResults.keySet())
                {
                    onColumn(m, isRelation, relations, entities, qResults.get(key), subManagedType, key.getBytes());
                }
            }
        }
        return entities;
    }

    /**
     * Find.
     *
     * @param m
     *            the m
     * @param relationNames
     *            the relation names
     * @param conditions
     *            the conditions
     * @return the list
     */
    public List<EnhanceEntity> find(EntityMetadata m, List<String> relationNames, List<IndexClause> conditions,
            int maxResult, List<String> columns)
    {
        return (List<EnhanceEntity>) find(conditions, m, true, relationNames, maxResult, columns);
    }

    /**
     * Find by range.
     *
     * @param minVal
     *            the min val
     * @param maxVal
     *            the max val
     * @param m
     *            the m
     * @param isWrapReq
     *            the is wrap req
     * @param relations
     *            the relations
     * @return the list
     * @throws Exception
     *             the exception
     */
    @Override
    public List findByRange(byte[] minVal, byte[] maxVal, EntityMetadata m, boolean isWrapReq, List<String> relations,
            List<String> columns, List<IndexExpression> conditions, int maxResults) throws Exception
    {
        Selector selector = clientFactory.getSelector(pool);

        SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, Integer.MAX_VALUE);
        if (columns != null && !columns.isEmpty())
        {
            slicePredicate = Selector.newColumnsPredicate(columns.toArray(new String[] {}));
        }

        KeyRange keyRange = selector.newKeyRange(minVal != null ? Bytes.fromByteArray(minVal) : Bytes.fromUTF8(""),
                maxVal != null ? Bytes.fromByteArray(maxVal) : Bytes.fromUTF8(""), maxResults);
        if (conditions != null)
        {
            keyRange.setRow_filter(conditions);
            keyRange.setRow_filterIsSet(true);
        }
        List<KeySlice> keys = selector.getKeySlices(new ColumnParent(m.getTableName()), keyRange, slicePredicate,
                getConsistencyLevel());

        List results = null;
        if (keys != null)
        {
            results = populateEntitiesFromKeySlices(m, isWrapReq, relations, keys, dataHandler);
        }

        if (log.isInfoEnabled())
        {
            log.info("Returning entities for find by range for", results != null ? results.size() : null);
        }

        return results;
    }

    public List<SearchResult> searchInInvertedIndex(String columnFamilyName, EntityMetadata m,
            Map<Boolean, List<IndexClause>> indexClauseMap)
    {
        // Delete from Inverted Index if applicable
        Object conn = getConnection();
        try
        {
            return invertedIndexHandler.search(m, getPersistenceUnit(), getConsistencyLevel(), indexClauseMap);
        }
        finally
        {
            releaseConnection(conn);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.impetus.client.cassandra.CassandraClientBase#getDataHandler()
     */
    @Override
    protected CassandraDataHandler getDataHandler()
    {
        return dataHandler;
    }

    protected IPooledConnection getConnection()
    {
        return clientFactory.getConnection(pool);
    }

    /**
     * Return cassandra client instance.
     *
     * @param connection
     * @return
     */
    protected Cassandra.Client getConnection(Object connection)
    {
        if (connection != null)
        {
            return ((IPooledConnection) connection).getAPI();
        }

        throw new KunderaException("Invalid configuration!, no available pooled connection found for:"
                + this.getClass().getSimpleName());
    }

    protected void releaseConnection(Object conn)
    {
        clientFactory.releaseConnection((IPooledConnection) conn);
    }

    @Override
    public Long generate(TableGeneratorDiscriptor discriptor)
    {
        return getGeneratedValue(discriptor, getPersistenceUnit());
    }

    Mutator getMutator()
    {
        return clientFactory.getMutator(pool);
    }

    Selector getSelector()
    {
        return clientFactory.getSelector(pool);
    }

    RowDeletor getRowDeletor()
    {
        return clientFactory.getRowDeletor(pool);
    }

    /**
     * Populate data.
     *
     * @param m
     *            the m
     * @param qResults
     *            the q results
     * @param entities
     *            the entities
     * @param isRelational
     *            the is relational
     * @param relationNames
     *            the relation names
     * @param dataHandler
     *            the data handler
     */
    private List populateData(EntityMetadata m, Map<Bytes, List<Column>> qResults, List<Object> entities,
            boolean isRelational, List<String> relationNames, CassandraDataHandler dataHandler)
    {
        if (m.getType().isSuperColumnFamilyMetadata())
        {
            Set<Bytes> primaryKeys = qResults.keySet();

            if (primaryKeys != null && !primaryKeys.isEmpty())
            {
                Object[] rowIds = new Object[primaryKeys.size()];
                int i = 0;
                for (Bytes b : primaryKeys)
                {
                    rowIds[i] = PropertyAccessorHelper.getObject(b, (Field) m.getIdAttribute().getJavaMember());
                    i++;
                }
                entities.addAll(findAll(m.getEntityClazz(), null, rowIds));
            }

        }
        else
        {
            Iterator<Bytes> rowIter = qResults.keySet().iterator();
            while (rowIter.hasNext())
            {
                Bytes rowKey = rowIter.next();
                List<Column> columns = qResults.get(rowKey);
                try
                {
                    Object id = PropertyAccessorHelper
                            .getObject(m.getIdAttribute().getJavaType(), rowKey.toByteArray());
                    Object e = null;
                    e = dataHandler.populateEntity(new ThriftRow(id, m.getTableName(), columns,
                            new ArrayList<SuperColumn>(0), new ArrayList<CounterColumn>(0),
                            new ArrayList<CounterSuperColumn>(0)), m, KunderaCoreUtils.getEntity(e), relationNames,
                            isRelational);
                    if (e != null)
                    {
                        entities.add(e);
                    }
                }
                catch (IllegalStateException e)
                {
                    log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e);
                    throw new KunderaException(e);
                }
                catch (Exception e)
                {
                    log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e);
                    throw new KunderaException(e);
                }
            }
        }
        return entities;
    }

    @Override
    public Object generate()
    {
        return super.getAutoGeneratedValue();
    }

}
TOP

Related Classes of com.impetus.client.cassandra.pelops.PelopsClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.