package com.kryptnostic.rhizome.configuration.cassandra; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.ProtocolOptions.Compression; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.kryptnostic.rhizome.configuration.amazon.AmazonConfiguration; public class CassandraConfiguration { private static final String CASSANDRA_COMPRESSION_PROPERTY = "compression"; private static final String CASSANDRA_RANDOM_PORTS_PROPERTY = "random-ports"; private static final String CASSANDRA_EMBEDDED_PROPERTY = "embedded"; private static final String CASSANDRA_SSL_ENABLED = "ssl-enabled"; private static final String CASSANDRA_KEYSPACE_PROPERTY = "keyspace"; private static final String CASSANDRA_REPLICATION_FACTOR = "replication-factor"; private static final String CASSANDRA_SEED_NODES_PROPERTY = "seed-nodes"; private static final String HAZELCAST_WRITE_DELAY_FIELD = "write-delay"; private static final String CASSANDRA_CONSISTENCY_LEVEL_PROPERTY = "consistency-level"; private static final List<String> CASSANDRA_SEED_DEFAULT = ImmutableList.of( "127.0.0.1" ); private static final String KEYSPACE_DEFAULT = "rhizome"; private static final int REPLICATION_FACTOR_DEFAULT = 1; private static final ConsistencyLevel CONSISTENCY_LEVEL_DEFAULT = ConsistencyLevel.QUORUM; private static final boolean RANDOM_PORTS_DEFAULT = false; private static final boolean EMBEDDED_DEFAULT = false; private static final boolean SSL_ENABLED_DEFAULT = false; private static final String COMPRESSION_DEFAULT = "NONE"; private final boolean randomPorts; private final boolean embedded; private final boolean sslEnabled; private final Compression compression; private List<InetAddress> cassandraSeedNodes; private final String keyspace; private final int replicationFactor; private final ConsistencyLevel consistencyLevel; private int writeBackDelay; private final String provider; private String region; private static final Logger logger = LoggerFactory .getLogger( CassandraConfiguration.class ); @JsonCreator public CassandraConfiguration( @JsonProperty( CASSANDRA_COMPRESSION_PROPERTY ) Optional<String> compression, @JsonProperty( CASSANDRA_RANDOM_PORTS_PROPERTY ) Optional<Boolean> randomPorts, @JsonProperty( CASSANDRA_EMBEDDED_PROPERTY ) Optional<Boolean> embedded, @JsonProperty( CASSANDRA_SSL_ENABLED ) Optional<Boolean> sslEnabled, @JsonProperty( CASSANDRA_SEED_NODES_PROPERTY ) Optional<List<String>> cassandraSeedNodes, @JsonProperty( CASSANDRA_KEYSPACE_PROPERTY ) Optional<String> keyspace, @JsonProperty( CASSANDRA_REPLICATION_FACTOR ) Optional<Integer> replicationFactor, @JsonProperty( CASSANDRA_CONSISTENCY_LEVEL_PROPERTY ) Optional<ConsistencyLevel> consistencyLevel, @JsonProperty( AmazonConfiguration.PROVIDER_PROPERTY ) Optional<String> provider, @JsonProperty( AmazonConfiguration.AWS_REGION_PROPERTY ) Optional<String> region, @JsonProperty( AmazonConfiguration.AWS_NODE_TAG_KEY_PROPERTY ) Optional<String> tagKey, @JsonProperty( AmazonConfiguration.AWS_NODE_TAG_VALUE_PROPERTY ) Optional<String> tagValue ) { this.randomPorts = randomPorts.or( RANDOM_PORTS_DEFAULT ); if ( this.randomPorts ) { logger.warn( "Starting cassandra in test mode" ); } this.embedded = embedded.or( EMBEDDED_DEFAULT ); this.sslEnabled = sslEnabled.or( SSL_ENABLED_DEFAULT ); this.keyspace = keyspace.or( KEYSPACE_DEFAULT ); this.replicationFactor = replicationFactor.or( REPLICATION_FACTOR_DEFAULT ); this.consistencyLevel = consistencyLevel.or( CONSISTENCY_LEVEL_DEFAULT ); // TODO: I don't think this switch statement is required as Jackson will correctly ser/des the enum. switch ( compression.or( COMPRESSION_DEFAULT ).toLowerCase() ) { case "lz4": this.compression = Compression.LZ4; break; case "snappy": this.compression = Compression.SNAPPY; break; default: this.compression = Compression.NONE; break; } this.provider = provider.orNull(); if ( "aws".equalsIgnoreCase( this.provider ) ) { this.region = region.or( AmazonConfiguration.AWS_REGION_DEFAULT ); this.cassandraSeedNodes = AmazonConfiguration.getNodesWithTagKeyAndValueInRegion( this.region, tagKey, tagValue, logger ); } else { this.cassandraSeedNodes = transformToInetAddresses( cassandraSeedNodes.or( CASSANDRA_SEED_DEFAULT ) ); } } private static List<InetAddress> transformToInetAddresses( List<String> addresses ) { Builder<InetAddress> builder = ImmutableList.<InetAddress> builder(); for ( String str : addresses ) { try { builder.add( InetAddress.getByName( str ) ); } catch ( UnknownHostException e ) { logger.error( "Could not find host {} specified in cassandra configuration in rhizome.yaml", str, e ); } } ImmutableList<InetAddress> list = builder.build(); if ( list.isEmpty() ) { return ImmutableList.<InetAddress> of( InetAddress.getLoopbackAddress() ); } return list; } @JsonProperty( AmazonConfiguration.PROVIDER_PROPERTY ) public String getProvider() { return provider; } @JsonProperty( AmazonConfiguration.AWS_REGION_PROPERTY ) public String getAwsRegion() { return region; } @JsonProperty( CASSANDRA_COMPRESSION_PROPERTY ) public Compression getCompression() { return compression; } @JsonProperty( CASSANDRA_RANDOM_PORTS_PROPERTY ) public boolean isRandomPorts() { return randomPorts; } @JsonProperty( CASSANDRA_EMBEDDED_PROPERTY ) public boolean isEmbedded() { return embedded; } @JsonProperty( CASSANDRA_SSL_ENABLED ) public boolean isSslEnabled() { return sslEnabled; } @JsonProperty( CASSANDRA_SEED_NODES_PROPERTY ) public List<InetAddress> getCassandraSeedNodes() { return cassandraSeedNodes; } @JsonProperty( CASSANDRA_KEYSPACE_PROPERTY ) public String getKeyspace() { return keyspace; } @JsonProperty( CASSANDRA_REPLICATION_FACTOR ) public int getReplicationFactor() { return replicationFactor; } @JsonProperty( CASSANDRA_CONSISTENCY_LEVEL_PROPERTY ) public ConsistencyLevel getConsistencyLevel() { return consistencyLevel; } @JsonProperty( HAZELCAST_WRITE_DELAY_FIELD ) public int getDefaultWriteBackDelay() { return writeBackDelay; } }