Package com.hmsonline.storm.cassandra.client

Source Code of com.hmsonline.storm.cassandra.client.AstyanaxClient

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.hmsonline.storm.cassandra.client;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import storm.trident.tuple.TridentTuple;
import backtype.storm.tuple.Tuple;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.hmsonline.storm.cassandra.StormCassandraConstants;
import com.hmsonline.storm.cassandra.bolt.mapper.Equality;
import com.hmsonline.storm.cassandra.bolt.mapper.TridentTupleMapper;
import com.hmsonline.storm.cassandra.bolt.mapper.TupleCounterMapper;
import com.hmsonline.storm.cassandra.bolt.mapper.TupleMapper;
import com.netflix.astyanax.AstyanaxConfiguration;
import com.netflix.astyanax.AstyanaxContext;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.Serializer;
import com.netflix.astyanax.annotations.Component;
import com.netflix.astyanax.connectionpool.ConnectionPoolConfiguration;
import com.netflix.astyanax.connectionpool.ConnectionPoolMonitor;
import com.netflix.astyanax.connectionpool.NodeDiscoveryType;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.impl.ConnectionPoolConfigurationImpl;
import com.netflix.astyanax.connectionpool.impl.ConnectionPoolType;
import com.netflix.astyanax.connectionpool.impl.SimpleAuthenticationCredentials;
import com.netflix.astyanax.connectionpool.impl.Slf4jConnectionPoolMonitorImpl;
import com.netflix.astyanax.impl.AstyanaxConfigurationImpl;
import com.netflix.astyanax.model.ByteBufferRange;
import com.netflix.astyanax.model.Column;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.ColumnList;
import com.netflix.astyanax.model.Composite;
import com.netflix.astyanax.query.RowQuery;
import com.netflix.astyanax.serializers.AnnotatedCompositeSerializer;
import com.netflix.astyanax.serializers.BigIntegerSerializer;
import com.netflix.astyanax.serializers.BooleanSerializer;
import com.netflix.astyanax.serializers.ByteBufferSerializer;
import com.netflix.astyanax.serializers.ByteSerializer;
import com.netflix.astyanax.serializers.BytesArraySerializer;
import com.netflix.astyanax.serializers.CompositeRangeBuilder;
import com.netflix.astyanax.serializers.CompositeSerializer;
import com.netflix.astyanax.serializers.DateSerializer;
import com.netflix.astyanax.serializers.DoubleSerializer;
import com.netflix.astyanax.serializers.FloatSerializer;
import com.netflix.astyanax.serializers.Int32Serializer;
import com.netflix.astyanax.serializers.LongSerializer;
import com.netflix.astyanax.serializers.ObjectSerializer;
import com.netflix.astyanax.serializers.ShortSerializer;
import com.netflix.astyanax.serializers.StringSerializer;
import com.netflix.astyanax.serializers.UUIDSerializer;
import com.netflix.astyanax.thrift.ThriftFamilyFactory;
import com.netflix.astyanax.util.RangeBuilder;

/**
*
* @param <K>
* @param <C>
* @param <V>
*/
public class AstyanaxClient<K, C, V> {
    private static final Logger LOG = LoggerFactory.getLogger(AstyanaxClient.class);
    public static final String CASSANDRA_CLUSTER_NAME = "cassandra.clusterName";
    public static final String ASTYANAX_CONFIGURATION = "astyanax.configuration";
    public static final String ASTYANAX_CONNECTION_POOL_CONFIGURATION = "astyanax.connectionPoolConfiguration";
    public static final String ASTYANAX_CONNECTION_POOL_MONITOR = "astyanax.connectioPoolMonitor";
    private Map<String, AstyanaxContext<Keyspace>> astyanaxContext = new HashMap<String, AstyanaxContext<Keyspace>>();



    // not static since we're carting instances around and do not want to share
    // them
    // between bolts
    private final Map<String, Object> DEFAULTS = new ImmutableMap.Builder<String, Object>()
            .put(CASSANDRA_CLUSTER_NAME, "ClusterName")
            .put(ASTYANAX_CONFIGURATION, new AstyanaxConfigurationImpl().setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
                .setConnectionPoolType(ConnectionPoolType.TOKEN_AWARE))
            .put(ASTYANAX_CONNECTION_POOL_CONFIGURATION,
                    new ConnectionPoolConfigurationImpl("MyConnectionPool"))
            .put(ASTYANAX_CONNECTION_POOL_MONITOR, new Slf4jConnectionPoolMonitorImpl()).build();

    protected List<AstyanaxContext<Keyspace>> createContext(Map<String, Object> config) {
        List<AstyanaxContext<Keyspace>> returnVal = new ArrayList<AstyanaxContext<Keyspace>>();
        Map<String, Object> settings = Maps.newHashMap();
        for (Map.Entry<String, Object> defaultEntry : DEFAULTS.entrySet()) {
            if (config.containsKey(defaultEntry.getKey())) {
                settings.put(defaultEntry.getKey(), config.get(defaultEntry.getKey()));
            } else {
                settings.put(defaultEntry.getKey(), defaultEntry.getValue());
            }
        }
        // in the defaults case, we don't know the seed hosts until context
        // creation time
        if (settings.get(ASTYANAX_CONNECTION_POOL_CONFIGURATION) instanceof ConnectionPoolConfigurationImpl) {
            ConnectionPoolConfigurationImpl cpConfig = (ConnectionPoolConfigurationImpl) settings
                    .get(ASTYANAX_CONNECTION_POOL_CONFIGURATION);
            cpConfig.setSeeds((String) config.get(StormCassandraConstants.CASSANDRA_HOST));
            Long port = (Long)config.get(StormCassandraConstants.CASSANDRA_PORT);
            if(port != null){
              cpConfig.setPort(port.intValue());
            }
           
            //
            String user = (String) config.get(StormCassandraConstants.CASSANDRA_USERNAME);

            if( user != null && ! user.trim().isEmpty() ){
                String password = config.containsKey(StormCassandraConstants.CASSANDRA_PASSWORD) ?
                    (String) config.get(StormCassandraConstants.CASSANDRA_PASSWORD) : "password";

            cpConfig.setAuthenticationCredentials(
                   new SimpleAuthenticationCredentials(new String(user), new String(password)));
            }
        }

        @SuppressWarnings("unchecked")
        Collection<String> keyspaces = (Collection<String>) config.get(StormCassandraConstants.CASSANDRA_KEYSPACE);
        for (String keyspace : keyspaces) {
            returnVal.add(new AstyanaxContext.Builder()
                            .forCluster((String) settings.get(CASSANDRA_CLUSTER_NAME))
                            .forKeyspace(keyspace)
                            .withAstyanaxConfiguration((AstyanaxConfiguration) settings.get(ASTYANAX_CONFIGURATION))
                            .withConnectionPoolConfiguration(
                                            (ConnectionPoolConfiguration) settings
                                                            .get(ASTYANAX_CONNECTION_POOL_CONFIGURATION))
                            .withConnectionPoolMonitor(
                                            (ConnectionPoolMonitor) settings.get(ASTYANAX_CONNECTION_POOL_MONITOR))
                            .buildKeyspace(ThriftFamilyFactory.getInstance()));
        }
        return returnVal;
    }

    public void start(Map<String, Object> config) {
        try {
            List<AstyanaxContext<Keyspace>> contexts = createContext(config);
            for (AstyanaxContext<Keyspace> context : contexts) {
                this.addAstyanaxContext(context.getKeyspaceName(), context);

                this.getAstyanaxContext(context.getKeyspaceName()).start();
                // test the connection
                this.getKeyspace(context.getKeyspaceName()).describeKeyspace();
            }
        } catch (Throwable e) {
            LOG.warn("Astyanax initialization failed.", e);
            throw new IllegalStateException("Failed to prepare Astyanax", e);
        }
    }

    public void stop() {
        this.getAstyanaxContext().shutdown();
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TupleMapper<K, C, V> tupleMapper, Tuple input) throws Exception {
        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();

        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));
        OperationResult<ColumnList<C>> result;
        result = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey).execute();
        ColumnList<C> columns = (ColumnList<C>) result.getResult();
        HashMap<C, V> retval = new HashMap<C, V>();
        Iterator<Column<C>> it = columns.iterator();
        while (it.hasNext()) {
            Column<C> col = it.next();
            retval.put(col.getName(), col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TridentTupleMapper<K, C, V> tupleMapper, TridentTuple input) throws Exception {
        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();

        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));
        OperationResult<ColumnList<C>> result;
        result = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey).execute();
        ColumnList<C> columns = (ColumnList<C>) result.getResult();
        HashMap<C, V> retval = new HashMap<C, V>();
        Iterator<Column<C>> it = columns.iterator();
        while (it.hasNext()) {
            Column<C> col = it.next();
            retval.put(col.getName(), col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TupleMapper<K, C, V> tupleMapper, Tuple input, List<C> slice) throws Exception {
        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();

        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));

        HashMap<C, V> retval = new HashMap<C, V>();
        for (C c : slice) {
            RowQuery<K, C> query = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey);
            query = query.withColumnRange(getRangeBuilder(c, c, null, (Serializer<C>) serializerFor(colClass)));
            OperationResult<ColumnList<C>> result = query.execute();
            Iterator<Column<C>> it = result.getResult().iterator();
            while (it.hasNext()) {
                Column<C> col = it.next();
                retval.put(col.getName(),
                        col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
            }
        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TridentTupleMapper<K, C, V> tupleMapper, TridentTuple input, List<C> slice)
            throws Exception {
        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();

        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));

        HashMap<C, V> retval = new HashMap<C, V>();
        for (C c : slice) {
            RowQuery<K, C> query = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey);
            query = query.withColumnRange(getRangeBuilder(c, c, null, (Serializer<C>) serializerFor(colClass)));

            OperationResult<ColumnList<C>> result = query.execute();

            LOG.debug("Selecting [" + c.toString() + "] returned [" + result.getResult().size() + "] results.");

            Iterator<Column<C>> it = result.getResult().iterator();
            while (it.hasNext()) {
                Column<C> col = it.next();
                LOG.debug("Adding [" + col.getName() + "]=>[" + col.getStringValue() + "]");
                retval.put(col.getName(),
                        col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
            }

        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TupleMapper<K, C, V> tupleMapper, Tuple input, C start, C end, Equality equality)
            throws Exception {
        if (start == null || end == null) {
            return null;
        }

        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();
        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));
        OperationResult<ColumnList<C>> result = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey)
                .withColumnRange(getRangeBuilder(start, end, equality, (Serializer<C>) serializerFor(colClass)))
                .execute();
        ColumnList<C> columns = (ColumnList<C>) result.getResult();
        HashMap<C, V> retval = new HashMap<C, V>();
        Iterator<Column<C>> it = columns.iterator();
        while (it.hasNext()) {
            Column<C> col = it.next();
            retval.put(col.getName(), col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public Map<C, V> lookup(TridentTupleMapper<K, C, V> tupleMapper, TridentTuple input, C start, C end,
            Equality equality) throws Exception {
        if (start == null || end == null) {
            return null;
        }

        String cf = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        Class<K> keyClass = tupleMapper.getKeyClass();
        Class<C> colClass = tupleMapper.getColumnNameClass();
        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(cf, (Serializer<K>) serializerFor(keyClass),
                (Serializer<C>) serializerFor(colClass));

        RowQuery<K, C> query = this.getKeyspace(keyspace).prepareQuery(columnFamily).getKey(rowKey);

        query = query.withColumnRange(getRangeBuilder(start, end, equality, (Serializer<C>) serializerFor(colClass)));

        OperationResult<ColumnList<C>> result = query.execute();
        ColumnList<C> columns = (ColumnList<C>) result.getResult();
        HashMap<C, V> retval = new HashMap<C, V>();
        Iterator<Column<C>> it = columns.iterator();
        while (it.hasNext()) {
            Column<C> col = it.next();
            retval.put(col.getName(), col.getValue((Serializer<V>) serializerFor(tupleMapper.getColumnValueClass())));
        }
        return retval;
    }

    @SuppressWarnings("unchecked")
    public void writeTuple(Tuple input, TupleMapper<K, C, V> tupleMapper) throws Exception {
        String columnFamilyName = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        MutationBatch mutation = getKeyspace(keyspace).prepareMutationBatch();
        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                (Serializer<C>) serializerFor(tupleMapper.getColumnNameClass()));
        this.addTupleToMutation(input, columnFamily, rowKey, mutation, tupleMapper);
        mutation.execute();
    }

    @SuppressWarnings("unchecked")
    public void writeTuple(TridentTuple input, TridentTupleMapper<K, C, V> tupleMapper) throws Exception {
        String columnFamilyName = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        MutationBatch mutation = getKeyspace(keyspace).prepareMutationBatch();
        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                (Serializer<C>) serializerFor(tupleMapper.getColumnNameClass()));
        this.addTupleToMutation(input, columnFamily, rowKey, mutation, tupleMapper);
        mutation.execute();
    }
   
    @SuppressWarnings({ "static-access", "unchecked" })
    public void writeTuples(List<TridentTuple> inputs, TridentTupleMapper<K, C, V> tupleMapper) throws Exception {
        Map<String, MutationBatch> mutations = new HashMap<String, MutationBatch>();
        for (TridentTuple input : inputs) {
            String keyspace = tupleMapper.mapToKeyspace(input);
            MutationBatch mutation = mutations.get(keyspace);
            if(mutation == null) {
                mutation = getKeyspace(keyspace).prepareMutationBatch();
                mutations.put(keyspace, mutation);
            }
           
            String columnFamilyName = tupleMapper.mapToColumnFamily(input);
            K rowKey = tupleMapper.mapToRowKey(input);
            ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                    (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                    (Serializer<C>) this.serializerFor(tupleMapper.getColumnNameClass()));
            this.addTupleToMutation(input, columnFamily, rowKey, mutation, tupleMapper);
        }
        for(String key : mutations.keySet()) {
            mutations.get(key).execute();
        }
    }

    @SuppressWarnings({ "static-access", "unchecked" })
    public void writeTuples(List<Tuple> inputs, TupleMapper<K, C, V> tupleMapper) throws Exception {
        Map<String, MutationBatch> mutations = new HashMap<String, MutationBatch>();
        for (Tuple input : inputs) {
            String keyspace = tupleMapper.mapToKeyspace(input);
            MutationBatch mutation = mutations.get(keyspace);
            if(mutation == null) {
                mutation = getKeyspace(keyspace).prepareMutationBatch();
                mutations.put(keyspace, mutation);
            }
           
            String columnFamilyName = tupleMapper.mapToColumnFamily(input);
            K rowKey = tupleMapper.mapToRowKey(input);
            ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                    (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                    (Serializer<C>) this.serializerFor(tupleMapper.getColumnNameClass()));
            this.addTupleToMutation(input, columnFamily, rowKey, mutation, tupleMapper);
        }
        for(String key : mutations.keySet()) {
            mutations.get(key).execute();
        }
    }

    @SuppressWarnings({ "static-access", "unchecked" })
    private void addTupleToMutation(Tuple input, ColumnFamily<K, C> columnFamily, K rowKey, MutationBatch mutation,
            TupleMapper<K, C, V> tupleMapper) {
        Map<C, V> columns = tupleMapper.mapToColumns(input);
        for (Map.Entry<C, V> entry : columns.entrySet()) {
            mutation.withRow(columnFamily, rowKey).putColumn(entry.getKey(), entry.getValue(),
                    (Serializer<V>) this.serializerFor(tupleMapper.getColumnValueClass()), null);
        }
    }

    private void addTupleToMutation(TridentTuple input, ColumnFamily<K, C> columnFamily, K rowKey,
            MutationBatch mutation, TridentTupleMapper<K, C, V> tupleMapper) {
        Map<C, V> columns = tupleMapper.mapToColumns(input);
        if (tupleMapper.shouldDelete(input)) {
            for (Map.Entry<C, V> entry : columns.entrySet()) {
                mutation.withRow(columnFamily, rowKey).deleteColumn(entry.getKey());
            }
        } else {
            for (Map.Entry<C, V> entry : columns.entrySet()) {
                mutation.withRow(columnFamily, rowKey).putColumn(entry.getKey(), entry.getValue(),
                        serializerFor(tupleMapper.getColumnValueClass()), null);
            }
        }
    }

    @SuppressWarnings("unchecked")
  public void incrementCountColumn(Tuple input, TupleCounterMapper<K,C> tupleMapper) throws Exception {
        String columnFamilyName = tupleMapper.mapToColumnFamily(input);
        String keyspace = tupleMapper.mapToKeyspace(input);
        K rowKey = tupleMapper.mapToRowKey(input);
        long incrementAmount = tupleMapper.mapToIncrementAmount(input);
        MutationBatch mutation = getKeyspace(keyspace).prepareMutationBatch();
        ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                (Serializer<C>) serializerFor(tupleMapper.getColumnNameClass()));
        for (C columnName : tupleMapper.mapToColumnList(input)) {
            mutation.withRow(columnFamily, rowKey).incrementCounterColumn(columnName, incrementAmount);
        }
        mutation.execute();
    }

    @SuppressWarnings("unchecked")
  public void incrementCountColumns(List<Tuple> inputs, TupleCounterMapper<K,C> tupleMapper) throws Exception {   
        Map<String, MutationBatch> mutations = new HashMap<String, MutationBatch>();
        for (Tuple input : inputs) {
            String keyspace = tupleMapper.mapToKeyspace(input);           
            MutationBatch mutation = mutations.get(keyspace);
            if(mutation == null) {
                mutation = getKeyspace(keyspace).prepareMutationBatch();
                mutations.put(keyspace, mutation);
            }
            String columnFamilyName = tupleMapper.mapToColumnFamily(input);
            K rowKey = tupleMapper.mapToRowKey(input);
            long incrementAmount = tupleMapper.mapToIncrementAmount(input);
            ColumnFamily<K, C> columnFamily = new ColumnFamily<K, C>(columnFamilyName,
                    (Serializer<K>) serializerFor(tupleMapper.getKeyClass()),
                    (Serializer<C>) serializerFor(tupleMapper.getColumnNameClass()));
            for (C columnName : tupleMapper.mapToColumnList(input)) {
                mutation.withRow(columnFamily, rowKey).incrementCounterColumn(columnName, incrementAmount);
            }
        }
        for(String key : mutations.keySet()) {
            mutations.get(key).execute();
        }
    }

    @SuppressWarnings({ "rawtypes" })
    private ByteBufferRange getRangeBuilder(C start, C end, Equality equality, Serializer<C> serializer)
            throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        if (!(serializer instanceof AnnotatedCompositeSerializer)) {
            return new RangeBuilder().setStart(start, serializerFor(start.getClass()))
                    .setEnd(end, serializerFor(end.getClass())).build();
        } else {
            AnnotatedCompositeSerializer compositeSerializer = (AnnotatedCompositeSerializer) serializer;
            CompositeRangeBuilder rangeBuilder = compositeSerializer.buildRange();
            List<ComponentField> componentFields = componentFieldsForClass(start.getClass());
            List<ComponentField> nonNullFields = new ArrayList<ComponentField>();
            for (ComponentField field : componentFields) {
                if ((field.getValue(start) != null) && field.getValue(end) != null) {
                    nonNullFields.add(field);
                }
            }

            for (int i = 0; i < nonNullFields.size(); i++) {
                Object objStart = nonNullFields.get(i).getValue(start);
                Object objEnd = nonNullFields.get(i).getValue(end);
                if (i + 1 != nonNullFields.size()) {
                    rangeBuilder.withPrefix(objStart);
                    LOG.debug("withPrefix(" + objStart + ")");
                } else {
                    rangeBuilder.greaterThanEquals(objStart);
                    LOG.debug("greaterThanEquals(" + objStart + ")");
                    rangeBuilder.lessThanEquals(objEnd);
                    LOG.debug("lessThanEquals(" + objEnd + ")");
                }
            }
            return rangeBuilder;
        }
    }

    static class ComponentField implements Comparable<ComponentField> {
        private Method getter;
        private int ordinal;

        ComponentField(Method getter, int ordinal) {
            this.getter = getter;
            this.ordinal = ordinal;
        }

        Object getValue(Object obj) throws IllegalAccessException, InvocationTargetException {
            return getter.invoke(obj);
        }

        @Override
        public int compareTo(ComponentField other) {
            return this.ordinal - other.ordinal;
        }
    }

    private static List<ComponentField> componentFieldsForClass(Class<?> c) throws IntrospectionException {
        ArrayList<ComponentField> retval = new ArrayList<ComponentField>();

        List<Field> fields = getInheritedFields(c);
        for (Field field : fields) {
            Component comp = field.getAnnotation(Component.class);
            if (comp != null) {
                retval.add(new ComponentField(new PropertyDescriptor(field.getName(), c).getReadMethod(), comp.ordinal()));
            }
        }
        Collections.sort(retval);
        return retval;
    }

    private static boolean containsComponentAnnotation(Class<?> c) {
        List<Field> fields = getInheritedFields(c);
        for (Field field : fields) {
            if (field.getAnnotation(Component.class) != null) {
                return true;
            }
        }
        return false;
    }

    private static List<Field> getInheritedFields(Class<?> type) {
        List<Field> result = new ArrayList<Field>();

        Class<?> i = type;
        while (i != null && i != Object.class) {
            for (Field field : i.getDeclaredFields()) {
                if (!field.isSynthetic()) {
                    result.add(field);
                }
            }
            i = i.getSuperclass();
        }

        return result;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static <T> Serializer<T> serializerFor(Class<?> valueClass) {
        Serializer serializer = null;
        if (valueClass.equals(UUID.class)) {
            serializer = UUIDSerializer.get();
        } else if (valueClass.equals(String.class)) {
            serializer = StringSerializer.get();
        } else if (valueClass.equals(Long.class) || valueClass.equals(long.class)) {
            serializer = LongSerializer.get();
        } else if (valueClass.equals(Integer.class) || valueClass.equals(int.class)) {
            serializer = Int32Serializer.get();
        } else if (valueClass.equals(Short.class) || valueClass.equals(short.class)) {
            serializer = ShortSerializer.get();
        } else if (valueClass.equals(Byte.class) || valueClass.equals(byte.class)) {
            serializer = ByteSerializer.get();
        } else if (valueClass.equals(Float.class) || valueClass.equals(float.class)) {
            serializer = FloatSerializer.get();
        } else if (valueClass.equals(Double.class) || valueClass.equals(double.class)) {
            serializer = DoubleSerializer.get();
        } else if (valueClass.equals(BigInteger.class)) {
            serializer = BigIntegerSerializer.get();
            // } else if (valueClass.equals(BigDecimal.class)) {
            // serializer = BigDecimalSerializer.get();
        } else if (valueClass.equals(Boolean.class) || valueClass.equals(boolean.class)) {
            serializer = BooleanSerializer.get();
        } else if (valueClass.equals(byte[].class)) {
            serializer = BytesArraySerializer.get();
        } else if (valueClass.equals(ByteBuffer.class)) {
            serializer = ByteBufferSerializer.get();
        } else if (valueClass.equals(Date.class)) {
            serializer = DateSerializer.get();
        } else if (valueClass.equals(Composite.class)) {
            serializer = CompositeSerializer.get();
        }

        if (serializer == null) {
            if (containsComponentAnnotation(valueClass)) {
                serializer = new AnnotatedCompositeSerializer(valueClass);
            } else {
                serializer = ObjectSerializer.get();
            }
        }
        return serializer;
    }
   
    public Keyspace getKeyspace() {
        return this.getAstyanaxContext().getEntity();
    }
   
    public Keyspace getKeyspace(String keyspace) {
        return this.getAstyanaxContext(keyspace).getEntity();
    }

    public AstyanaxContext<Keyspace> getAstyanaxContext() {
        if(astyanaxContext.size() == 1) {
            return astyanaxContext.values().iterator().next();
        } else {
            throw new IllegalArgumentException("if using no args get context there can only be one keyspace, instead there was " + astyanaxContext.size());
        }
    }

    public AstyanaxContext<Keyspace> getAstyanaxContext(String keyspace) {
        String keyspaceLower = keyspace.toLowerCase();
        AstyanaxContext<Keyspace> returnVal = astyanaxContext.get(keyspaceLower);
        if(returnVal == null) {
            throw new IllegalArgumentException("Cannnot find client for keyspace: " + keyspaceLower);
        }
        return returnVal;
    }

    public void addAstyanaxContext(String keyspace, AstyanaxContext<Keyspace> astyanaxContext) {
        this.astyanaxContext.put(keyspace.toLowerCase(), astyanaxContext);
    }
}
TOP

Related Classes of com.hmsonline.storm.cassandra.client.AstyanaxClient

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.