diff --git a/Readme.markdown b/Readme.markdown index 875be9981..ea5e34022 100644 --- a/Readme.markdown +++ b/Readme.markdown @@ -3,7 +3,24 @@ Astyanax Astyanax is a high level Java client for [Apache Cassandra](http://cassandra.apache.org). Apache Cassandra is a highly available column oriented database. -Astyanax is currently in use at [Netflix](http://movies.netflix.com), but is being [retired](https://medium.com/netflix-techblog/astyanax-retiring-an-old-friend-6cca1de9ac4). Fixes will be made for serious issues, but it is not under active development. +Astyanax is currently in use at [Netflix](http://movies.netflix.com), but is being [retired](https://medium.com/netflix-techblog/astyanax-retiring-an-old-friend-6cca1de9ac4). +Astyanax is no longer under active development, but may receive dependency updates to ease migration away from Astyanax. + +In place of Astyanax consider using [DataStax Java Driver for Apache Cassandra](https://github.com/datastax/java-driver) +which is under active development and encapsulates a lot of lessons learned from Astyanax. The DataStax driver supports +only CQL protocol because Apache Cassandra 4.x drops the Thrift protocol. Switching to the DataStax driver requires +using CQL queries, but you'll still be able to access legacy column families via the CQL "with compact storage" option. + +This version of Astyanax shades its dependency on cassandra-all so you can optionally select any version +of cassandra-unit you like for unit/integration testing with different versions of Cassandra. When upgrading to this +verion of Astyanax you may need to: +* Explicitly add any cassandra-all transitive dependencies you previously silently depended on via Astayanax transitives. +* If you were using internal features of Astyanax that (unintentionally) publicly exposed cassandra-all classes, +you must either: + * Option A (best): Migrate away from Astyanax to [DataStax Java Driver for Apache Cassandra](https://github.com/datastax/java-driver). + * Option B (second-best): Use only astyanax-core public interfaces (none of them expose cassandra-all classes). + * Option C: Switch your objects from "org.apache.cassandra" to the shaded "com.netflix.astyanax.shaded.org.apache.cassandra" + package Astyanax now depends on. Artifacts ------------------------------- @@ -12,19 +29,26 @@ Astyanax jars are published to Maven Central. As of astyanax 1.56.27 the projec Required artifacts -|GroupID/Org|ArtifactID/Name| -| --------- | ------------- | -|com.netflix.astyanax|astyanax-core| -|com.netflix.astyanax|astyanax-thrift| -|com.netflix.astyanax|astyanax-cassandra| +|GroupID/Org|ArtifactID/Name|Desc| +| --------- | ------------- |----| +|com.netflix.astyanax|astyanax-thrift or astyanax-cql|Choose Thrift or CQL protocol. Note Cassandra 4.x+ drops support for Thrift protocol.| + +Transitive artifacts (dependencies automatically added via a required artifact) + +|GroupID/Org|ArtifactID/Name|Desc| +| --------- | ------------- |----| +|com.netflix.astyanax|astyanax-core|Astyanax's public interface.| +|com.netflix.astyanax|astyanax-cassandra|Cassandra-specific features shared by astyanax-thrift and astyanax-cql| +|com.netflix.astyanax|astyanax-cassandra-all-shaded|Shaded version of cassandra-all for the few classes used by astyanax-cassandra so projects are free to select arbitrary versions of cassandra-unit for unit/integration testing against newer versions of Cassandra. Hides Astyanax's dependency on cassandra-all by refactoring "org.apache.cassandra" classes to "com.netflix.astyanax.shaded.org.apache.cassandra".| Optional artifacts -|GroupID/Org|ArtifactID/Name| -| --------- | ------------- | -|com.netflix.astyanax|astyanax-queue| -|com.netflix.astyanax|astyanax-entity-mapper| -|com.netflix.astyanax|astyanax-recipes| +|GroupID/Org|ArtifactID/Name|Desc| +| --------- | ------------- |----| +|com.netflix.astyanax|astyanax-contrib|Optional integration with other commonly-used Netflix OSS modules.| +|com.netflix.astyanax|astyanax-queue|Queue implementation backed by Cassandra storage. Use at your own risk -- Cassandra can be a *very bad* storage engine for queues. If you insist on using Cassandra for queues, set a very short TTL and use DateTieredCompactionStrategy (DTCS).| +|com.netflix.astyanax|astyanax-entity-mapper|| +|com.netflix.astyanax|astyanax-recipes|Optional implementations of some common patterns. Use at your own risk; some of these are popular but not well-suite for Cassandra for many use cases (looking at you, AllRowsReader).| Features -------- @@ -45,6 +69,13 @@ Documentation ------------- Detailed documentation of Astyanax's features and usage can be found on the [wiki](https://github.com/Netflix/astyanax/wiki) and the [getting started guide](https://github.com/Netflix/astyanax/wiki/Getting-Started). +IntelliJ: currently (June 2018) IntelliJ has a bug which renders an "unfound" error for packages relocated via another +module in the same project (e.g. shaded classes from astyanax-cassandra-all-shaded). +This affects *only* the Astyanax project itself within IntelliJ; Astyanax still builds perfectly fine via Gradle. +Astyanax users are unaffected. For more details see: + +* [https://github.com/johnrengelman/shadow/issues/264](https://github.com/johnrengelman/shadow/issues/264) +* [https://youtrack.jetbrains.com/issue/IDEA-163411](https://youtrack.jetbrains.com/issue/IDEA-163411) Ancient History --------------- diff --git a/astyanax-cassandra-all-shaded/build.gradle b/astyanax-cassandra-all-shaded/build.gradle new file mode 100644 index 000000000..e9b6c3aef --- /dev/null +++ b/astyanax-cassandra-all-shaded/build.gradle @@ -0,0 +1,41 @@ +/** + * Shaded version of cassandra-all for the few classes used by astyanax-cassandra. Shading frees projects to select + * arbitrary versions of cassandra-unit for unit/integration testing against newer versions of Cassandra. + * Hides Astyanax's dependency on cassandra-all by refactoring "org.apache.cassandra" classes to + * "com.netflix.astyanax.shaded.org.apache.cassandra". + */ + +plugins { + id 'com.github.johnrengelman.plugin-shadow' version '2.0.3' + id 'java' +} + +print "Shading cassandra-all for cassandraVersion=${cassandraVersion}\n" + +dependencies { + compile ("org.apache.cassandra:cassandra-all:$cassandraVersion") { + // Exclude all those heavy transitive dependencies because Astyanax doesn't need them + transitive = false + } +} + +shadowJar { + // Don't append default "-all" to end of shaded jar name. + classifier = '' + + // Add only the shaded cassandra-all classes + dependencies { + include( + dependency('org.apache.cassandra:cassandra-all::.*') + ) + } + + // Shaded/rename cassandra-all class packages + relocate("org.apache.cassandra", "com.netflix.astyanax.shaded.org.apache.cassandra") +} + +tasks.build.dependsOn(shadowJar) + +// Create only the shadow jar containing the shaded classes +tasks.jar.setEnabled(false) +tasks.jar.dependsOn(tasks.shadowJar) diff --git a/astyanax-cassandra/build.gradle b/astyanax-cassandra/build.gradle index 0cbbbccba..fc2253025 100644 --- a/astyanax-cassandra/build.gradle +++ b/astyanax-cassandra/build.gradle @@ -1,19 +1,19 @@ apply plugin: 'osgi' +/** + * Cassandra-specific features shared by astyanax-thrift and astyanax-cql. + */ dependencies { - compile project(':astyanax-core') - compile ("org.apache.cassandra:cassandra-all:$cassandraVersion") { - force = true - transitive = false - } + compile project(':astyanax-core') + + // Shaded version of cassandra-all for the few simple classes Astyanax actually uses. + // Also excludes cassandra-all's transitive dependencies. + compile project(path: ':astyanax-cassandra-all-shaded', configuration: 'shadow') + compile "org.xerial.snappy:snappy-java:$snappyVersion" compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion" - compile "org.apache.cassandra:cassandra-thrift:$cassandraThriftVersion" compile "org.apache.servicemix.bundles:org.apache.servicemix.bundles.commons-csv:$commonsCsvVersion" compile "org.codehaus.jettison:jettison:$jettisonVersion" compile "commons-codec:commons-codec:$commonsCodecVersion" compile "org.slf4j:slf4j-api:$slf4jVersion" - testCompile "junit:junit:$junitVersion" } - - diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/impl/AstyanaxConfigurationImpl.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/impl/AstyanaxConfigurationImpl.java index 124fd65c3..e3f8631ad 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/impl/AstyanaxConfigurationImpl.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/impl/AstyanaxConfigurationImpl.java @@ -53,9 +53,11 @@ public class AstyanaxConfigurationImpl implements AstyanaxConfiguration { private int maxThriftSize = 16384000; public AstyanaxConfigurationImpl() { - partitioners.put(org.apache.cassandra.dht.RandomPartitioner.class.getCanonicalName(), BigInteger127Partitioner.get()); + partitioners.put("org.apache.cassandra.dht.RandomPartitioner", + BigInteger127Partitioner.get()); try { - partitioners.put(org.apache.cassandra.dht.Murmur3Partitioner.class.getCanonicalName(), Murmur3Partitioner.get()); + partitioners.put("org.apache.cassandra.dht.Murmur3Partitioner", + Murmur3Partitioner.get()); } catch (NoClassDefFoundError exception) { // We ignore this for backwards compatiblity with pre 1.2 cassandra. diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/model/AbstractComposite.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/model/AbstractComposite.java index 99daa3c1a..440be0584 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/model/AbstractComposite.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/model/AbstractComposite.java @@ -27,8 +27,7 @@ import java.util.Map; import java.util.logging.Logger; -import org.apache.cassandra.utils.ByteBufferUtil; - +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.ByteBufferUtil; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableClassToInstanceMap; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/BigInteger127Partitioner.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/BigInteger127Partitioner.java index c95288213..a9d8b4c2e 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/BigInteger127Partitioner.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/BigInteger127Partitioner.java @@ -21,7 +21,7 @@ import java.util.Iterator; import java.util.List; -import org.apache.cassandra.dht.RandomPartitioner; +import com.netflix.astyanax.shaded.org.apache.cassandra.dht.RandomPartitioner; import com.google.common.collect.Lists; import com.netflix.astyanax.Serializer; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/Murmur3Partitioner.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/Murmur3Partitioner.java index fd1785009..10e4099d2 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/Murmur3Partitioner.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/partitioner/Murmur3Partitioner.java @@ -32,7 +32,8 @@ public class Murmur3Partitioner implements Partitioner { public static final BigInteger ONE = new BigInteger("1"); - private static final org.apache.cassandra.dht.Murmur3Partitioner partitioner = new org.apache.cassandra.dht.Murmur3Partitioner(); + private static final com.netflix.astyanax.shaded.org.apache.cassandra.dht.Murmur3Partitioner partitioner = + new com.netflix.astyanax.shaded.org.apache.cassandra.dht.Murmur3Partitioner(); private static final Murmur3Partitioner instance = new Murmur3Partitioner(); public static Partitioner get() { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/AsciiSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/AsciiSerializer.java index d98b88d5c..496fdafac 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/AsciiSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/AsciiSerializer.java @@ -18,7 +18,7 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; -import org.apache.cassandra.db.marshal.AsciiType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AsciiType; /** * Almost identical to StringSerializer except we use the US-ASCII character set diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigDecimalSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigDecimalSerializer.java index 51669a188..cfd05f9c4 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigDecimalSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigDecimalSerializer.java @@ -18,7 +18,7 @@ import java.math.BigDecimal; import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.DecimalType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.DecimalType; public class BigDecimalSerializer extends AbstractSerializer { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigIntegerSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigIntegerSerializer.java index 8756934de..8c8bb8951 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigIntegerSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BigIntegerSerializer.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.IntegerType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.IntegerType; /** * Serializer implementation for BigInteger diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BooleanSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BooleanSerializer.java index e69de7a90..f4899e889 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BooleanSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BooleanSerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.BooleanType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.BooleanType; /** * Converts bytes to Boolean and vice versa diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteBufferSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteBufferSerializer.java index dc7941c3a..4df7b49d6 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteBufferSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteBufferSerializer.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Map; -import org.apache.cassandra.db.marshal.BytesType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.BytesType; /** * The BytesExtractor is a simple identity function. It supports the Extractor diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteSerializer.java index b5ee5de5a..1f31eca06 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ByteSerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.IntegerType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.IntegerType; public class ByteSerializer extends AbstractSerializer { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BytesArraySerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BytesArraySerializer.java index 3ffe6666b..ac17b0865 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BytesArraySerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/BytesArraySerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.BytesType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.BytesType; import com.netflix.astyanax.Serializer; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ComparatorType.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ComparatorType.java index 975a5f548..cc0130e4b 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ComparatorType.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ComparatorType.java @@ -15,32 +15,35 @@ */ package com.netflix.astyanax.serializers; -import com.netflix.astyanax.*; +import com.netflix.astyanax.Serializer; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ShadedTypeParser; + +import static com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ShadedTypeParser.SHADED_PREFIX; /** * @author: peter */ public enum ComparatorType { - ASCIITYPE("org.apache.cassandra.db.marshal.AsciiType", AsciiSerializer.get()), - BYTESTYPE("org.apache.cassandra.db.marshal.BytesType", ByteBufferSerializer.get()), - INTEGERTYPE("org.apache.cassandra.db.marshal.IntegerType", BigIntegerSerializer.get()), - INT32TYPE("org.apache.cassandra.db.marshal.Int32Type", Int32Serializer.get()), - DECIMALTYPE("org.apache.cassandra.db.marshal.DecimalType", BigDecimalSerializer.get()), - LEXICALUUIDTYPE("org.apache.cassandra.db.marshal.LexicalUUIDType", UUIDSerializer.get()), - LOCALBYPARTITIONERTYPE("org.apache.cassandra.db.marshal.LocalByPartionerType", ByteBufferSerializer.get()), // FIXME - LONGTYPE("org.apache.cassandra.db.marshal.LongType", LongSerializer.get()), - TIMEUUIDTYPE("org.apache.cassandra.db.marshal.TimeUUIDType", TimeUUIDSerializer.get()), - UTF8TYPE("org.apache.cassandra.db.marshal.UTF8Type", StringSerializer.get()), - COMPOSITETYPE("org.apache.cassandra.db.marshal.CompositeType", CompositeSerializer.get()), - DYNAMICCOMPOSITETYPE("org.apache.cassandra.db.marshal.DynamicCompositeType", DynamicCompositeSerializer.get()), - UUIDTYPE("org.apache.cassandra.db.marshal.UUIDType", UUIDSerializer.get()), - COUNTERTYPE("org.apache.cassandra.db.marshal.CounterColumnType", LongSerializer.get()), - DOUBLETYPE("org.apache.cassandra.db.marshal.DoubleType", DoubleSerializer.get()), - FLOATTYPE("org.apache.cassandra.db.marshal.FloatType", FloatSerializer.get()), - BOOLEANTYPE("org.apache.cassandra.db.marshal.BooleanType", BooleanSerializer.get()), - DATETYPE("org.apache.cassandra.db.marshal.DateType", DateSerializer.get()), - REVERSEDTYPE("org.apache.cassandra.db.marshal.ReversedType", ReversedSerializer.get()); + ASCIITYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.AsciiType", AsciiSerializer.get()), + BYTESTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.BytesType", ByteBufferSerializer.get()), + INTEGERTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.IntegerType", BigIntegerSerializer.get()), + INT32TYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.Int32Type", Int32Serializer.get()), + DECIMALTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.DecimalType", BigDecimalSerializer.get()), + LEXICALUUIDTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.LexicalUUIDType", UUIDSerializer.get()), + LOCALBYPARTITIONERTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.LocalByPartionerType", ByteBufferSerializer.get()), // FIXME + LONGTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.LongType", LongSerializer.get()), + TIMEUUIDTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.TimeUUIDType", TimeUUIDSerializer.get()), + UTF8TYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.UTF8Type", StringSerializer.get()), + COMPOSITETYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.CompositeType", CompositeSerializer.get()), + DYNAMICCOMPOSITETYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.DynamicCompositeType", DynamicCompositeSerializer.get()), + UUIDTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.UUIDType", UUIDSerializer.get()), + COUNTERTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.CounterColumnType", LongSerializer.get()), + DOUBLETYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.DoubleType", DoubleSerializer.get()), + FLOATTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.FloatType", FloatSerializer.get()), + BOOLEANTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.BooleanType", BooleanSerializer.get()), + DATETYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.DateType", DateSerializer.get()), + REVERSEDTYPE(SHADED_PREFIX + "org.apache.cassandra.db.marshal.ReversedType", ReversedSerializer.get()); private final String className; private final String typeName; @@ -48,12 +51,7 @@ public enum ComparatorType { private ComparatorType(String className, Serializer serializer) { this.className = className; - if (className.startsWith("org.apache.cassandra.db.marshal.")) { - typeName = className.substring("org.apache.cassandra.db.marshal.".length()); - } - else { - typeName = className; - } + this.typeName = getShadedTypeName(className); this.serializer = serializer; } @@ -73,15 +71,19 @@ public static ComparatorType getByClassName(String className) { if (className == null) { return null; } - for (ComparatorType type : ComparatorType.values()) { - if (type.getClassName().equals(className)) { - return type; - } - if (type.getClassName().equals("org.apache.cassandra.db.marshal." + className)) { + if (type.getClassName().equals(getShadedClassName(className))) { return type; } } return null; } + + public static String getShadedClassName(String className){ + return ShadedTypeParser.getShadedClassName(className); + } + + public static String getShadedTypeName(String typeName){ + return ShadedTypeParser.getShadedTypeName(typeName); + } } diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DateSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DateSerializer.java index 601f6f679..c9d5cf069 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DateSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DateSerializer.java @@ -18,7 +18,7 @@ import java.nio.ByteBuffer; import java.util.Date; -import org.apache.cassandra.db.marshal.DateType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.DateType; /** * Converts bytes to Date and vice versa, by first converting the Date to or diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DoubleSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DoubleSerializer.java index 7a6494836..c577f0781 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DoubleSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/DoubleSerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.DoubleType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.DoubleType; /** * Uses LongSerializer via translating Doubles to and from raw long bytes form. diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/FloatSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/FloatSerializer.java index 51efc1b25..90c8d0442 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/FloatSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/FloatSerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.FloatType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.FloatType; /** * Uses IntSerializer via translating Float objects to and from raw long bytes diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/GzipStringSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/GzipStringSerializer.java index 91146e1ed..a82c23268 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/GzipStringSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/GzipStringSerializer.java @@ -23,7 +23,7 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import org.apache.commons.codec.binary.StringUtils; public class GzipStringSerializer extends AbstractSerializer { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ListSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ListSerializer.java index 31277b801..3924e531c 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ListSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ListSerializer.java @@ -18,10 +18,8 @@ import java.nio.ByteBuffer; import java.util.List; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.ListType; - -import com.netflix.astyanax.serializers.AbstractSerializer; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ListType; /** * Serializer implementation for generic lists. diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/LongSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/LongSerializer.java index 32033b81e..5e8efbfdc 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/LongSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/LongSerializer.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.LongType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.LongType; /** * Converts bytes to Long and vise a versa diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/MapSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/MapSerializer.java index 8b7f0093d..8b030102e 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/MapSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/MapSerializer.java @@ -15,14 +15,12 @@ */ package com.netflix.astyanax.serializers; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.MapType; + import java.nio.ByteBuffer; import java.util.Map; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.MapType; - -import com.netflix.astyanax.serializers.AbstractSerializer; - /** * Serializer implementation for generic maps. * diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SerializerPackageImpl.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SerializerPackageImpl.java index 489ac8e66..264183fc2 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SerializerPackageImpl.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SerializerPackageImpl.java @@ -23,16 +23,15 @@ import java.util.Map.Entry; import java.util.Set; -import org.apache.cassandra.db.marshal.CompositeType; -import org.apache.cassandra.db.marshal.ReversedType; -import org.apache.cassandra.db.marshal.TypeParser; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.CompositeType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ReversedType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ShadedTypeParser; import org.apache.commons.lang.StringUtils; import com.netflix.astyanax.Serializer; import com.netflix.astyanax.SerializerPackage; import com.netflix.astyanax.ddl.ColumnDefinition; import com.netflix.astyanax.ddl.ColumnFamilyDefinition; -//import org.apache.cassandra.config.ConfigurationException; /** * Basic implementation of SerializerPackage which can be configured either from @@ -118,7 +117,7 @@ public SerializerPackageImpl setKeyType(String keyType) throws UnknownComparator if (type == ComparatorType.COMPOSITETYPE) { try { - this.keySerializer = new SpecificCompositeSerializer((CompositeType) TypeParser.parse(keyType)); + this.keySerializer = new SpecificCompositeSerializer((CompositeType) ShadedTypeParser.parse(keyType)); return this; } catch (Exception e) { @@ -132,7 +131,7 @@ else if (type == ComparatorType.DYNAMICCOMPOSITETYPE) { } else if (type == ComparatorType.REVERSEDTYPE) { try { - this.keySerializer = new SpecificReversedSerializer((ReversedType) TypeParser.parse(keyType)); + this.keySerializer = new SpecificReversedSerializer((ReversedType) ShadedTypeParser.parse(keyType)); return this; } catch (Exception e) { @@ -160,6 +159,7 @@ public SerializerPackageImpl setColumnType(String columnType) throws UnknownComp @SuppressWarnings("rawtypes") public SerializerPackageImpl setColumnNameType(String columnType) throws UnknownComparatorException { // Determine the column serializer + columnType = ComparatorType.getShadedClassName(columnType); String comparatorType = StringUtils.substringBefore(columnType, "("); ComparatorType type = ComparatorType.getByClassName(comparatorType); if (type == null) { @@ -168,7 +168,7 @@ public SerializerPackageImpl setColumnNameType(String columnType) throws Unknown if (type == ComparatorType.COMPOSITETYPE) { try { - this.columnSerializer = new SpecificCompositeSerializer((CompositeType) TypeParser.parse(columnType)); + this.columnSerializer = new SpecificCompositeSerializer((CompositeType) ShadedTypeParser.parse(columnType)); return this; } catch (Exception e) { @@ -182,7 +182,7 @@ else if (type == ComparatorType.DYNAMICCOMPOSITETYPE) { } else if (type == ComparatorType.REVERSEDTYPE) { try { - this.columnSerializer = new SpecificReversedSerializer((ReversedType) TypeParser.parse(columnType)); + this.columnSerializer = new SpecificReversedSerializer((ReversedType) ShadedTypeParser.parse(columnType)); return this; } catch (Exception e) { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SetSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SetSerializer.java index 7438644ba..5fc9531a0 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SetSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SetSerializer.java @@ -18,8 +18,8 @@ import java.nio.ByteBuffer; import java.util.Set; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.SetType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.SetType; import com.netflix.astyanax.serializers.AbstractSerializer; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ShortSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ShortSerializer.java index d6d05ee87..510e27ba1 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ShortSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/ShortSerializer.java @@ -17,11 +17,11 @@ import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.IntegerType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.IntegerType; /** - * {@link Serializer} for {@link Short}s (no pun intended). - * + * {@link com.netflix.astyanax.Serializer} for {@link Short}s (no pun intended). + * */ public final class ShortSerializer extends AbstractSerializer { diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SnappyStringSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SnappyStringSerializer.java index 334acbbe0..2f07935b4 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SnappyStringSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SnappyStringSerializer.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import org.apache.commons.codec.binary.StringUtils; import org.xerial.snappy.SnappyInputStream; import org.xerial.snappy.SnappyOutputStream; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificCompositeSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificCompositeSerializer.java index cadd90cf8..936f4e10b 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificCompositeSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificCompositeSerializer.java @@ -19,8 +19,8 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.CompositeType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.CompositeType; import com.google.common.base.Preconditions; @@ -34,10 +34,7 @@ public SpecificCompositeSerializer(CompositeType type) { comparators = new ArrayList( type.types.size() ); for ( AbstractType compType : type.types ) { String typeName = compType.toString(); - if ( typeName.startsWith( "org.apache.cassandra.db.marshal." ) ) { - typeName = typeName.substring( "org.apache.cassandra.db.marshal.".length() ); - } - comparators.add( typeName ); + comparators.add( ComparatorType.getShadedTypeName(typeName) ); } } diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificReversedSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificReversedSerializer.java index af75db0bf..3f6623ac1 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificReversedSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/SpecificReversedSerializer.java @@ -16,8 +16,8 @@ package com.netflix.astyanax.serializers; import java.nio.ByteBuffer; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.ReversedType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ReversedType; import com.google.common.base.Preconditions; @SuppressWarnings("rawtypes") @@ -30,9 +30,7 @@ public SpecificReversedSerializer(ReversedType type) { Preconditions.checkNotNull(type); AbstractType compType = type.baseType; reversedTypeName = compType.toString(); - if ( reversedTypeName.startsWith( "org.apache.cassandra.db.marshal." ) ) { - reversedTypeName = reversedTypeName.substring( "org.apache.cassandra.db.marshal.".length() ); - } + reversedTypeName = ComparatorType.getShadedTypeName(reversedTypeName); this.reversedComparatorType = ComparatorType.getByClassName(reversedTypeName); } diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/StringSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/StringSerializer.java index c812585f3..72d759172 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/StringSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/StringSerializer.java @@ -18,7 +18,7 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; /** * A StringSerializer translates the byte[] to and from string using utf-8 diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/TimeUUIDSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/TimeUUIDSerializer.java index fa20ef3bc..6b3b4ef9d 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/TimeUUIDSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/TimeUUIDSerializer.java @@ -16,12 +16,11 @@ package com.netflix.astyanax.serializers; import java.nio.ByteBuffer; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; -import org.apache.cassandra.db.marshal.TimeUUIDType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.TimeUUIDType; import com.netflix.astyanax.util.TimeUUIDUtils; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/UUIDSerializer.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/UUIDSerializer.java index 39e934c3f..ef30207aa 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/UUIDSerializer.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/serializers/UUIDSerializer.java @@ -18,7 +18,7 @@ import java.nio.ByteBuffer; import java.util.UUID; -import org.apache.cassandra.db.marshal.UUIDType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UUIDType; /** * A UUIDSerializer translates the byte[] to and from UUID types. diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/shaded/org/apache/cassandra/db/marshal/ShadedTypeParser.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/shaded/org/apache/cassandra/db/marshal/ShadedTypeParser.java new file mode 100644 index 000000000..c41c7c1aa --- /dev/null +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/shaded/org/apache/cassandra/db/marshal/ShadedTypeParser.java @@ -0,0 +1,411 @@ +/******************************************************************************* + * Copyright 2018 Netflix + * + * 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.netflix.astyanax.shaded.org.apache.cassandra.db.marshal; + +import com.netflix.astyanax.shaded.org.apache.cassandra.exceptions.ConfigurationException; +import com.netflix.astyanax.shaded.org.apache.cassandra.exceptions.SyntaxException; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.ByteBufferUtil; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.FBUtilities; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.util.*; + +/** + * Extend TypeParser to support shaded {@link AbstractType} from shaded package. + * Converts input class names to shaded package name. + * + * Note that shading prefixes this class's package name with the shaded name {@link #SHADED_PREFIX}. + * + * Effectively uses {@link TypeParser} only as an interface. The implementation is a slightly altered copy-paste + * of {@link TypeParser} because {@link TypeParser#parse(String)} can't really be overridden. That method is public but + * references private fields (e.g. {@link TypeParser#idx}, etc.) and private methods + * ({@link TypeParser#getAbstractType}, etc.) which a derived class can't access. + * + * This is a very ugly way to support shading cassandra-all, but it's still the least invasive approach. + */ +public class ShadedTypeParser extends TypeParser { + public static final String SHADED_PREFIX = "com.netflix.astyanax.shaded."; + protected final String str; + protected int idx; + protected static final Map> cache = new HashMap(); + protected static final TypeParser EMPTY_PARSER = new ShadedTypeParser(""); + + public static ShadedTypeParser buildTypeParser(String str, int idx){ + return new ShadedTypeParser(str, idx); + } + + public ShadedTypeParser(String str) { + // TypeParser's private fields aren't actually used, but we're still required to invoke the super constructor + super(str); + this.str = str; + this.idx = 0; + } + + public ShadedTypeParser(String str, int idx) { + // TypeParser's private fields aren't actually used, but we're still required to invoke the super constructor + super(str); + this.str = str; + this.idx = idx; + } + + public static String getShadedClassName(String className){ + if(className.startsWith(SHADED_PREFIX)){ + return className; + } else if (className.contains(".")){ + return SHADED_PREFIX + className; + } else { + return SHADED_PREFIX + "org.apache.cassandra.db.marshal." + className; + } + } + + public static String getShadedTypeName(String typeName){ + if ( typeName.startsWith( "org.apache.cassandra.db.marshal." ) ) { + return typeName.substring( "org.apache.cassandra.db.marshal.".length() ); + } else if ( typeName.startsWith( SHADED_PREFIX + "org.apache.cassandra.db.marshal." ) ) { + return typeName.substring( (SHADED_PREFIX + "org.apache.cassandra.db.marshal.").length() ); + } + return typeName; + } + + public static AbstractType parse(String str) throws SyntaxException, ConfigurationException { + if (str == null) { + return BytesType.instance; + } else { + str = getShadedClassName(str); + AbstractType type = (AbstractType)cache.get(str); + if (type != null) { + return type; + } else { + int i = 0; + i = skipBlank(str, i); + + int j; + for(j = i; !isEOS(str, i) && isIdentifierChar(str.charAt(i)); ++i) { + ; + } + + if (i == j) { + return BytesType.instance; + } else { + String name = str.substring(j, i); + name = getShadedClassName(name); + i = skipBlank(str, i); + if (!isEOS(str, i) && str.charAt(i) == '(') { + ShadedTypeParser typeParser = buildTypeParser(str, i); + type = getAbstractType(name, typeParser); + } else { + type = getAbstractType(name); + } + + cache.put(str, type); + return type; + } + } + } + } + + public AbstractType parse() throws SyntaxException, ConfigurationException { + this.skipBlank(); + String name = this.readNextIdentifier(); + name = getShadedClassName(name); + this.skipBlank(); + return !this.isEOS() && this.str.charAt(this.idx) == '(' ? getAbstractType(name, this) : getAbstractType(name); + } + + public Map getKeyValueParameters() throws SyntaxException { + Map map = new HashMap(); + if (this.isEOS()) { + return map; + } else if (this.str.charAt(this.idx) != '(') { + throw new IllegalStateException(); + } else { + ++this.idx; + + String k; + String v; + for(; this.skipBlankAndComma(); map.put(k, v)) { + if (this.str.charAt(this.idx) == ')') { + ++this.idx; + return map; + } + + k = this.readNextIdentifier(); + v = ""; + this.skipBlank(); + if (this.str.charAt(this.idx) == '=') { + ++this.idx; + this.skipBlank(); + v = this.readNextIdentifier(); + } else if (this.str.charAt(this.idx) != ',' && this.str.charAt(this.idx) != ')') { + this.throwSyntaxError("unexpected character '" + this.str.charAt(this.idx) + "'"); + } + } + + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", this.str, this.idx)); + } + } + + public List> getTypeParameters() throws SyntaxException, ConfigurationException { + List> list = new ArrayList(); + if (this.isEOS()) { + return list; + } else if (this.str.charAt(this.idx) != '(') { + throw new IllegalStateException(); + } else { + ++this.idx; + + while(this.skipBlankAndComma()) { + if (this.str.charAt(this.idx) == ')') { + ++this.idx; + return list; + } + + try { + list.add(this.parse()); + } catch (SyntaxException var4) { + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", this.str, this.idx)); + ex.initCause(var4); + throw ex; + } + } + + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", this.str, this.idx)); + } + } + + public Map> getAliasParameters() throws SyntaxException, ConfigurationException { + Map> map = new HashMap(); + if (this.isEOS()) { + return map; + } else if (this.str.charAt(this.idx) != '(') { + throw new IllegalStateException(); + } else { + ++this.idx; + + while(this.skipBlankAndComma()) { + if (this.str.charAt(this.idx) == ')') { + ++this.idx; + return map; + } + + String alias = this.readNextIdentifier(); + if (alias.length() != 1) { + this.throwSyntaxError("An alias should be a single character"); + } + + char aliasChar = alias.charAt(0); + if (aliasChar < '!' || aliasChar > 127) { + this.throwSyntaxError("An alias should be a single character in [0..9a..bA..B-+._&]"); + } + + this.skipBlank(); + if (this.str.charAt(this.idx) != '=' || this.str.charAt(this.idx + 1) != '>') { + this.throwSyntaxError("expecting '=>' token"); + } + + this.idx += 2; + this.skipBlank(); + + try { + map.put((byte)aliasChar, this.parse()); + } catch (SyntaxException var6) { + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", this.str, this.idx)); + ex.initCause(var6); + throw ex; + } + } + + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", this.str, this.idx)); + } + } + + public Map getCollectionsParameters() throws SyntaxException, ConfigurationException { + Map map = new HashMap(); + if (this.isEOS()) { + return map; + } else if (this.str.charAt(this.idx) != '(') { + throw new IllegalStateException(); + } else { + ++this.idx; + + while(this.skipBlankAndComma()) { + if (this.str.charAt(this.idx) == ')') { + ++this.idx; + return map; + } + + String bbHex = this.readNextIdentifier(); + ByteBuffer bb = null; + + try { + bb = ByteBufferUtil.hexToBytes(bbHex); + } catch (NumberFormatException var7) { + this.throwSyntaxError(var7.getMessage()); + } + + this.skipBlank(); + if (this.str.charAt(this.idx) != ':') { + this.throwSyntaxError("expecting ':' token"); + } + + ++this.idx; + this.skipBlank(); + + try { + AbstractType type = this.parse(); + if (!(type instanceof CollectionType)) { + throw new SyntaxException(type.toString() + " is not a collection type"); + } + + map.put(bb, (CollectionType)type); + } catch (SyntaxException var6) { + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", this.str, this.idx)); + ex.initCause(var6); + throw ex; + } + } + + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", this.str, this.idx)); + } + } + + protected static AbstractType getAbstractType(String compareWith) throws ConfigurationException { + String className = getShadedClassName(compareWith); + Class typeClass = FBUtilities.classForName(className, "abstract-type"); + + try { + Field field = typeClass.getDeclaredField("instance"); + return (AbstractType)field.get((Object)null); + } catch (NoSuchFieldException var4) { + return getRawAbstractType(typeClass, EMPTY_PARSER); + } catch (IllegalAccessException var5) { + return getRawAbstractType(typeClass, EMPTY_PARSER); + } + } + + protected static AbstractType getAbstractType(String compareWith, TypeParser parser) throws SyntaxException, ConfigurationException { + String className = getShadedClassName(compareWith); + Class typeClass = FBUtilities.classForName(className, "abstract-type"); + + AbstractType type; + try { + Method method = typeClass.getDeclaredMethod("getInstance", TypeParser.class); + return (AbstractType)method.invoke((Object)null, parser); + } catch (NoSuchMethodException var6) { + type = getRawAbstractType(typeClass); + return AbstractType.parseDefaultParameters(type, parser); + } catch (IllegalAccessException var7) { + type = getRawAbstractType(typeClass); + return AbstractType.parseDefaultParameters(type, parser); + } catch (InvocationTargetException var8) { + ConfigurationException ex = new ConfigurationException("Invalid definition for comparator " + typeClass.getName() + "."); + ex.initCause(var8.getTargetException()); + throw ex; + } + } + + protected static AbstractType getRawAbstractType(Class> typeClass) throws ConfigurationException { + try { + Field field = typeClass.getDeclaredField("instance"); + return (AbstractType)field.get((Object)null); + } catch (NoSuchFieldException var2) { + throw new ConfigurationException("Invalid comparator class " + typeClass.getName() + ": must define a public static instance field or a public static method getInstance(TypeParser)."); + } catch (IllegalAccessException var3) { + throw new ConfigurationException("Invalid comparator class " + typeClass.getName() + ": must define a public static instance field or a public static method getInstance(TypeParser)."); + } + } + + protected static AbstractType getRawAbstractType(Class> typeClass, TypeParser parser) throws ConfigurationException { + try { + Method method = typeClass.getDeclaredMethod("getInstance", TypeParser.class); + return (AbstractType)method.invoke((Object)null, parser); + } catch (NoSuchMethodException var4) { + throw new ConfigurationException("Invalid comparator class " + typeClass.getName() + ": must define a public static instance field or a public static method getInstance(TypeParser)."); + } catch (IllegalAccessException var5) { + throw new ConfigurationException("Invalid comparator class " + typeClass.getName() + ": must define a public static instance field or a public static method getInstance(TypeParser)."); + } catch (InvocationTargetException var6) { + ConfigurationException ex = new ConfigurationException("Invalid definition for comparator " + typeClass.getName() + "."); + ex.initCause(var6.getTargetException()); + throw ex; + } + } + + protected void throwSyntaxError(String msg) throws SyntaxException { + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: %s", this.str, this.idx, msg)); + } + + protected boolean isEOS() { + return isEOS(this.str, this.idx); + } + + protected static boolean isEOS(String str, int i) { + return i >= str.length(); + } + + protected static boolean isBlank(int c) { + return c == 32 || c == 9 || c == 10; + } + + protected void skipBlank() { + this.idx = skipBlank(this.str, this.idx); + } + + protected static int skipBlank(String str, int i) { + while(!isEOS(str, i) && isBlank(str.charAt(i))) { + ++i; + } + + return i; + } + + protected boolean skipBlankAndComma() { + for(boolean commaFound = false; !this.isEOS(); ++this.idx) { + int c = this.str.charAt(this.idx); + if (c == ',') { + if (commaFound) { + return true; + } + + commaFound = true; + } else if (!isBlank(c)) { + return true; + } + } + + return false; + } + + protected static boolean isIdentifierChar(int c) { + return c >= 48 && c <= 57 || c >= 97 && c <= 122 || c >= 65 && c <= 90 || c == 45 || c == 43 || c == 46 || c == 95 || c == 38; + } + + public String readNextIdentifier() { + int i; + for(i = this.idx; !this.isEOS() && isIdentifierChar(this.str.charAt(this.idx)); ++this.idx) { + ; + } + + return this.str.substring(i, this.idx); + } + + public char readNextChar() { + this.skipBlank(); + return this.str.charAt(this.idx++); + } +} diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/ColumnarRecordWriter.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/ColumnarRecordWriter.java index 176b02d64..7d4578fe1 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/ColumnarRecordWriter.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/ColumnarRecordWriter.java @@ -19,7 +19,7 @@ import java.util.Iterator; import java.util.List; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import com.netflix.astyanax.ColumnListMutation; import com.netflix.astyanax.Keyspace; diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvColumnReader.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvColumnReader.java index fafbd4c8c..7eacf108d 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvColumnReader.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvColumnReader.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import org.apache.commons.csv.CSVParser; /** diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvRecordReader.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvRecordReader.java index c4d934eb8..540af9d58 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvRecordReader.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/CsvRecordReader.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import org.apache.commons.csv.CSVParser; /** diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordReader.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordReader.java index b6734de6d..080ed874e 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordReader.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordReader.java @@ -18,7 +18,7 @@ import java.io.IOException; import java.util.List; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; /** * diff --git a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordWriter.java b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordWriter.java index 1307b8d42..26aa4f25c 100644 --- a/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordWriter.java +++ b/astyanax-cassandra/src/main/java/com/netflix/astyanax/util/RecordWriter.java @@ -17,7 +17,7 @@ import java.util.List; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; diff --git a/astyanax-cassandra/src/main/resources/cassandra2-template.yaml b/astyanax-cassandra/src/main/resources/cassandra2-template.yaml index fe88ac21f..a14107f4c 100644 --- a/astyanax-cassandra/src/main/resources/cassandra2-template.yaml +++ b/astyanax-cassandra/src/main/resources/cassandra2-template.yaml @@ -28,7 +28,7 @@ seed_provider: - seeds: 127.0.0.1 concurrent_reads: 32 concurrent_writes: 64 -memtable_flush_queue_size: 4 +#memtable_flush_queue_size: 4 trickle_fsync: false trickle_fsync_interval_in_kb: 10240 storage_port: $STORAGE_PORT$ @@ -45,10 +45,10 @@ incremental_backups: false snapshot_before_compaction: false auto_snapshot: false column_index_size_in_kb: 64 -in_memory_compaction_limit_in_mb: 128 -multithreaded_compaction: false +#in_memory_compaction_limit_in_mb: 128 +#multithreaded_compaction: false compaction_throughput_mb_per_sec: 128 -compaction_preheat_key_cache: true +#compaction_preheat_key_cache: true read_request_timeout_in_ms: 10000 range_request_timeout_in_ms: 10000 write_request_timeout_in_ms: 10000 @@ -62,7 +62,7 @@ dynamic_snitch_badness_threshold: 0.1 request_scheduler: org.apache.cassandra.scheduler.NoScheduler index_interval: 256 inter_dc_tcp_nodelay: true -memtable_total_space_in_mb: 1024 +#memtable_total_space_in_mb: 1024 rpc_min_threads: 16 rpc_max_threads: 2048 stream_throughput_outbound_megabits_per_sec: '400' @@ -70,6 +70,6 @@ dynamic_snitch: true concurrent_compactors: 1 num_tokens: 1 auto_bootstrap: true -preheat_kernel_page_cache: false +#preheat_kernel_page_cache: false cas_contention_timeout_in_ms: 1000 file_cache_size_in_mb: '512' \ No newline at end of file diff --git a/astyanax-contrib/build.gradle b/astyanax-contrib/build.gradle index 047a58b81..cb565329a 100644 --- a/astyanax-contrib/build.gradle +++ b/astyanax-contrib/build.gradle @@ -1,12 +1,9 @@ +/** + * Optional integration with other commonly-used Netflix OSS modules. + */ dependencies { - compile project(':astyanax-cassandra') compile project(':astyanax-core') compile project(':astyanax-thrift') - compile 'com.netflix.eureka:eureka-client:1.1.110' - compile 'com.netflix.archaius:archaius-core:0.5.12' - compile ("com.google.guava:guava:$guavaVersion") { - force = true - } - compile "org.slf4j:slf4j-api:$slf4jVersion" - testCompile "junit:junit:$junitVersion" + compile 'com.netflix.eureka:eureka-client:1.9.0' + compile 'com.netflix.archaius:archaius-core:0.7.6' } diff --git a/astyanax-core/build.gradle b/astyanax-core/build.gradle index f44860df3..054bf9756 100644 --- a/astyanax-core/build.gradle +++ b/astyanax-core/build.gradle @@ -1,17 +1,13 @@ apply plugin: 'osgi' +/** + * Astyanax's public interface. + */ dependencies { compile "joda-time:joda-time:$jodaTimeVersion" compile "com.github.stephenc.high-scale-lib:high-scale-lib:$highScaleLibVersion" - compile ("com.google.guava:guava:$guavaVersion") { - force = true - } + compile "com.google.guava:guava:$guavaVersion" compile "com.eaio.uuid:uuid:$uuidVersion" compile "org.slf4j:slf4j-api:$slf4jVersion" compile "commons-lang:commons-lang:$commonsLangVersion" - testCompile "junit:junit:$junitVersion" - - compile("org.apache.cassandra:cassandra-all:$cassandraVersion") { - exclude group: 'org.apache.cassandra.deps' - } } diff --git a/astyanax-cql/build.gradle b/astyanax-cql/build.gradle index 73a1c431d..4d0e43c2b 100644 --- a/astyanax-cql/build.gradle +++ b/astyanax-cql/build.gradle @@ -1,18 +1,16 @@ apply plugin: 'osgi' +/** + * CQL protocol implementation of astyanax-core + */ dependencies { - compile project(':astyanax-core') - compile project(':astyanax-cassandra') + compile project(':astyanax-core') + compile project(':astyanax-cassandra') compile ("com.datastax.cassandra:cassandra-driver-core:$javaDriverVersion") { - //exclude group: 'com.google.guava', module: 'guava' transitive = false } - compile "io.netty:netty:$nettyVersion" - compile "com.google.guava:guava:$guavaVersion" compile "net.jpountz.lz4:lz4:$lz4Version" compile "com.codahale.metrics:metrics-core:$metricCoreVersion" compile "org.xerial.snappy:snappy-java:$snappyVersion" - } - diff --git a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBridge.java b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBridge.java index 13dc4e7fd..09deaaee0 100644 --- a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBridge.java +++ b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBridge.java @@ -15,16 +15,7 @@ */ package com.netflix.astyanax.cql; -import com.datastax.driver.core.AuthProvider; -import com.datastax.driver.core.Configuration; -import com.datastax.driver.core.ConsistencyLevel; -import com.datastax.driver.core.HostDistance; -import com.datastax.driver.core.MetricsOptions; -import com.datastax.driver.core.PlainTextAuthProvider; -import com.datastax.driver.core.PoolingOptions; -import com.datastax.driver.core.ProtocolOptions; -import com.datastax.driver.core.QueryOptions; -import com.datastax.driver.core.SocketOptions; +import com.datastax.driver.core.*; import com.datastax.driver.core.policies.LoadBalancingPolicy; import com.datastax.driver.core.policies.Policies; import com.datastax.driver.core.policies.RoundRobinPolicy; @@ -34,6 +25,8 @@ import com.netflix.astyanax.connectionpool.ConnectionPoolConfiguration; import com.netflix.astyanax.cql.util.ConsistencyLevelTransform; +import static com.datastax.driver.core.ProtocolOptions.DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS; + public class JavaDriverConfigBridge { private final AstyanaxConfiguration asConfig; @@ -45,20 +38,21 @@ public JavaDriverConfigBridge(AstyanaxConfiguration asConfig, ConnectionPoolConf } public Configuration getJDConfig() { - - return new Configuration(getPolicies(), - getProtocolOptions(), - getPoolingOptions(), - getSocketOptions(), - getMetricsOptions(), - getQueryOptions()); + + return Configuration.builder() + .withPolicies(getPolicies()) + .withProtocolOptions(getProtocolOptions()) + .withPoolingOptions(getPoolingOptions()) + .withSocketOptions(getSocketOptions()) + .withMetricsOptions(getMetricsOptions()) + .withQueryOptions(getQueryOptions()) + .build(); } private Policies getPolicies() { - return new Policies(getLB(), - Policies.defaultReconnectionPolicy(), - Policies.defaultRetryPolicy(), - Policies.defaultAddressTranslater()); + return Policies.builder() + .withLoadBalancingPolicy(getLB()) + .build(); } private LoadBalancingPolicy getLB() { @@ -78,16 +72,16 @@ private LoadBalancingPolicy getLB() { private ProtocolOptions getProtocolOptions() { int port = cpConfig.getPort(); - int protocolVersion = -1; // use default - + AuthProvider authProvider = AuthProvider.NONE; AuthenticationCredentials creds = cpConfig.getAuthenticationCredentials(); if (creds != null) { authProvider = new PlainTextAuthProvider(creds.getUsername(), creds.getPassword()); } - - return new ProtocolOptions(port, protocolVersion, null, authProvider); + + return new ProtocolOptions(port, ProtocolVersion.NEWEST_SUPPORTED, DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS, + null, authProvider); } private PoolingOptions getPoolingOptions() { diff --git a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBuilder.java b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBuilder.java index 60d49a3ce..ab9eb5ea4 100644 --- a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBuilder.java +++ b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/JavaDriverConfigBuilder.java @@ -66,20 +66,19 @@ public JavaDriverConfigBuilder() { } public JavaDriverConnectionPoolConfigurationImpl build() { - - Policies policies = new Policies(loadBalancingPolicy, reconnectionPolicy, retryPolicy); + Policies policies = Policies.builder() + .withLoadBalancingPolicy(loadBalancingPolicy) + .withReconnectionPolicy(reconnectionPolicy) + .withRetryPolicy(retryPolicy).build(); ProtocolOptions protocolOptions = (nativeProtocolPort == -1) ? new ProtocolOptions() : new ProtocolOptions(nativeProtocolPort); - PoolingOptions poolOptions = poolingOptions; - SocketOptions sockOptions = socketOptions; - MetricsOptions metricsOptions = new MetricsOptions(jmxReportingEnabled); - QueryOptions qOptions = queryOptions; - - return new JavaDriverConnectionPoolConfigurationImpl(new Configuration(policies, - protocolOptions, - poolOptions, - sockOptions, - metricsOptions, - qOptions)); + MetricsOptions metricsOptions = new MetricsOptions(true, jmxReportingEnabled); + return new JavaDriverConnectionPoolConfigurationImpl(Configuration.builder() + .withPolicies(policies) + .withProtocolOptions(protocolOptions) + .withPoolingOptions(poolingOptions) + .withSocketOptions(socketOptions) + .withMetricsOptions(metricsOptions) + .withQueryOptions(queryOptions).build()); } @@ -114,12 +113,13 @@ public JavaDriverConfigBuilder withMaxConnsPerHost(HostDistance distance, int ma } public JavaDriverConfigBuilder withMinRequestsPerConnection(HostDistance distance, int minRequests) { - this.poolingOptions.setMinSimultaneousRequestsPerConnectionThreshold(distance, minRequests); + + this.poolingOptions.setNewConnectionThreshold(distance, minRequests); return this; } public JavaDriverConfigBuilder withMaxRequestsPerConnection(HostDistance distance, int maxRequests) { - this.poolingOptions.setMaxSimultaneousRequestsPerConnectionThreshold(distance, maxRequests); + this.poolingOptions.setMaxRequestsPerConnection(distance, maxRequests); return this; } diff --git a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/reads/model/CqlColumnImpl.java b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/reads/model/CqlColumnImpl.java index 37c9bcfb0..54fd896bb 100644 --- a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/reads/model/CqlColumnImpl.java +++ b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/reads/model/CqlColumnImpl.java @@ -39,31 +39,31 @@ import com.netflix.astyanax.serializers.UUIDSerializer; /** - * Class that implements the {@link Column} interface. - * + * Class that implements the {@link Column} interface. + * * Note that since columns can be rows in CQL3, this class needs access to the java driver {@link Row} * within the java driver {@link ResultSet} - * - * The index provided within the row indicates where to start parsing the Column data. - * Also this class handles reading the TTL and Timestamp on the Column as well. - * + * + * The index provided within the row indicates where to start parsing the Column data. + * Also this class handles reading the TTL and Timestamp on the Column as well. + * * @author poberai * * @param */ public class CqlColumnImpl implements Column { - private Row row; - private C columnName; + private Row row; + private C columnName; private int index; - + private ComparatorType cType; - + private boolean isBlob = false; - + public CqlColumnImpl() { } - + public CqlColumnImpl(C colName, Row row, int index) { this.columnName = colName; this.row = row; @@ -72,9 +72,8 @@ public CqlColumnImpl(C colName, Row row, int index) { Definition colDefinition = row.getColumnDefinitions().asList().get(index); isBlob = colDefinition.getType() == DataType.blob(); } - + public CqlColumnImpl(C colName, Row row, int index, Definition colDefinition) { - this.columnName = colName; this.row = row; this.index = index; @@ -86,7 +85,7 @@ public CqlColumnImpl(C colName, Row row, int index, Definition colDefinition) { public C getName() { return columnName; } - + @Override public ByteBuffer getRawName() { return StringSerializer.get().toByteBuffer(String.valueOf(columnName)); @@ -158,9 +157,13 @@ public ByteBuffer getByteBufferValue() { return row.getBytes(index); } + /** + * @return {@link Date} from {@link com.datastax.driver.core.GettableByIndexData#getTimestamp(int)} for backwards- + * compatibility because this {@link #getTimestamp()} returns column timestamp, not value of a Date-based column. + */ @Override public Date getDateValue() { - return (isBlob) ? DateSerializer.get().fromByteBuffer(row.getBytes(index)) : row.getDate(index); + return (isBlob) ? DateSerializer.get().fromByteBuffer(row.getBytes(index)) : row.getTimestamp(index); } @Override @@ -189,19 +192,17 @@ public int getTtl() { public boolean hasValue() { return (row != null) && !(row.isNull(index)); } - public Object getGenericValue() { ComparatorType cType = getComparatorType(); return CqlTypeMapping.getDynamicColumn(row, cType.getSerializer(), index, null); } - + public ComparatorType getComparatorType() { - if (cType != null) { return cType; } - + // Lazy init DataType type = row.getColumnDefinitions().getType(index); if (type.isCollection()) { @@ -209,7 +210,7 @@ public ComparatorType getComparatorType() { } String typeString = (type.getName().name()).toUpperCase(); cType = CqlTypeMapping.getComparatorFromCqlType(typeString); - + return cType; } } diff --git a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/retrypolicies/ChangeConsistencyLevelRetryPolicy.java b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/retrypolicies/ChangeConsistencyLevelRetryPolicy.java index 511d5c1b9..7b126909a 100644 --- a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/retrypolicies/ChangeConsistencyLevelRetryPolicy.java +++ b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/retrypolicies/ChangeConsistencyLevelRetryPolicy.java @@ -15,9 +15,11 @@ */ package com.netflix.astyanax.cql.retrypolicies; +import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.Statement; import com.datastax.driver.core.WriteType; +import com.datastax.driver.core.exceptions.DriverException; import com.datastax.driver.core.policies.RetryPolicy.RetryDecision; import com.netflix.astyanax.cql.ConsistencyLevelMapping; @@ -112,6 +114,22 @@ public RetryDecision onUnavailable(Statement query, ConsistencyLevel cl, boolean shouldRetry = retryOnAllConditions || retryOnUnavailable; return checkRetry(query, cl, shouldRetry); } + + @Override + public RetryDecision onRequestError(Statement query, ConsistencyLevel cl, DriverException e, int nbRetry) { + boolean shouldRetry = retryOnAllConditions || retryOnUnavailable; + return checkRetry(query, cl, shouldRetry); + } + + @Override + public void init(Cluster cluster) { + // Do nothing + } + + @Override + public void close() { + // Do nothing + } }; @Override diff --git a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/schema/CqlColumnDefinitionImpl.java b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/schema/CqlColumnDefinitionImpl.java index 0eece6eb0..e5b3e8894 100644 --- a/astyanax-cql/src/main/java/com/netflix/astyanax/cql/schema/CqlColumnDefinitionImpl.java +++ b/astyanax-cql/src/main/java/com/netflix/astyanax/cql/schema/CqlColumnDefinitionImpl.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; diff --git a/astyanax-entity-mapper/build.gradle b/astyanax-entity-mapper/build.gradle index 01e5310e4..56f3ff020 100644 --- a/astyanax-entity-mapper/build.gradle +++ b/astyanax-entity-mapper/build.gradle @@ -1,13 +1,6 @@ dependencies { - compile project(':astyanax-core') - compile project(':astyanax-cassandra') - compile project(':astyanax-recipes') - compile "javax.persistence:persistence-api:$jpaVersion" - compile ("com.google.guava:guava:$guavaVersion") { - force = true - } - compile "org.slf4j:slf4j-api:$slf4jVersion" - compile "commons-lang:commons-lang:$commonsLangVersion" - testCompile project(':astyanax-thrift') - testCompile "junit:junit:$junitVersion" + compile project(':astyanax-core') + compile project(':astyanax-cassandra') + compile project(':astyanax-recipes') + compile "javax.persistence:persistence-api:$jpaVersion" } diff --git a/astyanax-entity-mapper/src/main/java/com/netflix/astyanax/entitystore/CompositeEntityMapper.java b/astyanax-entity-mapper/src/main/java/com/netflix/astyanax/entitystore/CompositeEntityMapper.java index 97b532081..90035ff28 100644 --- a/astyanax-entity-mapper/src/main/java/com/netflix/astyanax/entitystore/CompositeEntityMapper.java +++ b/astyanax-entity-mapper/src/main/java/com/netflix/astyanax/entitystore/CompositeEntityMapper.java @@ -300,7 +300,7 @@ public String toString() { } public String getKeyType() { - return idMapper.getSerializer().getComparatorType().getClassName(); + return idMapper.getSerializer().getComparatorType().getTypeName(); } /** @@ -359,7 +359,7 @@ public String getComparatorType() { sb.append(StringUtils.join( Collections2.transform(components, new Function, String>() { public String apply(FieldMapper input) { - return input.serializer.getComparatorType().getClassName(); + return input.serializer.getComparatorType().getTypeName(); } }), ",")); @@ -386,7 +386,7 @@ public static ByteBuffer getBytes(ByteBuffer bb, int length) { } String getValueType() { - return valueMapper.getSerializer().getComparatorType().getClassName(); + return valueMapper.getSerializer().getComparatorType().getTypeName(); } ByteBuffer[] getQueryEndpoints(Collection predicates) { diff --git a/astyanax-examples/build.gradle b/astyanax-examples/build.gradle index 8cc2b9643..0fea6f7bb 100644 --- a/astyanax-examples/build.gradle +++ b/astyanax-examples/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile project(':astyanax-core') - compile project(':astyanax-cassandra') - compile project(':astyanax-thrift') - compile project(':astyanax-contrib') + compile project(':astyanax-core') + compile project(':astyanax-cassandra') + compile project(':astyanax-thrift') + compile project(':astyanax-contrib') compile "org.slf4j:slf4j-api:$slf4jVersion" } diff --git a/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstCQLClient.java b/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstCQLClient.java index c60e0732a..ee66a1c4b 100644 --- a/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstCQLClient.java +++ b/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstCQLClient.java @@ -17,6 +17,7 @@ import static com.netflix.astyanax.examples.ModelConstants.*; +import com.netflix.astyanax.ddl.KeyspaceDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +39,8 @@ import com.netflix.astyanax.serializers.StringSerializer; import com.netflix.astyanax.thrift.ThriftFamilyFactory; +import java.util.Properties; + /** * Example code for demonstrating how to access Cassandra using Astyanax and CQL3. * @@ -47,9 +50,10 @@ public class AstCQLClient { private static final Logger logger = LoggerFactory.getLogger(AstCQLClient.class); - private AstyanaxContext context; + private AstyanaxContext keyspaceContext; private Keyspace keyspace; private ColumnFamily EMP_CF; + private static final String KEYSPACE_NAME = "test1"; private static final String EMP_CF_NAME = "employees1"; private static final String INSERT_STATEMENT = String.format("INSERT INTO %s (%s, %s, %s, %s) VALUES (?, ?, ?, ?);", @@ -62,9 +66,9 @@ public class AstCQLClient { public void init() { logger.debug("init()"); - context = new AstyanaxContext.Builder() + keyspaceContext = new AstyanaxContext.Builder() .forCluster("Test Cluster") - .forKeyspace("test1") + .forKeyspace(KEYSPACE_NAME) .withAstyanaxConfiguration(new AstyanaxConfigurationImpl() .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE) ) @@ -79,15 +83,43 @@ public void init() { .withConnectionPoolMonitor(new CountingConnectionPoolMonitor()) .buildKeyspace(ThriftFamilyFactory.getInstance()); - context.start(); - keyspace = context.getEntity(); + keyspaceContext.start(); + + // Create keyspace if it doesn't already exist. + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + Keyspace ks = createKeyspaceIfNotExists(); + + keyspace = keyspaceContext.getEntity(); EMP_CF = ColumnFamily.newColumnFamily( EMP_CF_NAME, IntegerSerializer.get(), StringSerializer.get()); + + // Create column family if it doesn't already exist. + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + createColumnFamilyIfNotExists(); } - + + private Keyspace createKeyspaceIfNotExists() { + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + Keyspace ks = null; + try { + ks = keyspaceContext.getClient(); + + Properties props = new Properties(); + props.setProperty("name", KEYSPACE_NAME); + props.setProperty("strategy_class", "SimpleStrategy"); + props.setProperty("strategy_options.replication_factor", "1"); + + ks.createKeyspaceIfNotExists(props); + KeyspaceDefinition ksDef = ks.describeKeyspace(); + } catch (Exception e) { + logger.info("Didn't (re)create keyspace, message={}", e.getMessage()); + } + return ks; + } + public void insert(int empId, int deptId, String firstName, String lastName) { try { @SuppressWarnings("unused") @@ -126,7 +158,8 @@ public void insertDynamicProperties(int id, String[] ... entries) { } - public void createCF() { + public void createColumnFamilyIfNotExists() { + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. logger.debug("CQL: "+CREATE_STATEMENT); try { @SuppressWarnings("unused") @@ -134,9 +167,8 @@ public void createCF() { .prepareQuery(EMP_CF) .withCql(CREATE_STATEMENT) .execute(); - } catch (ConnectionException e) { - logger.error("failed to create CF", e); - throw new RuntimeException("failed to create CF", e); + } catch (Exception e) { + logger.info("Didn't (re)create column family, message={}", e.getMessage()); } } diff --git a/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstClient.java b/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstClient.java index 785ec7c5b..9a28ce324 100644 --- a/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstClient.java +++ b/astyanax-examples/src/main/java/com/netflix/astyanax/examples/AstClient.java @@ -18,7 +18,9 @@ import static com.netflix.astyanax.examples.ModelConstants.*; import java.util.Iterator; +import java.util.Properties; +import com.netflix.astyanax.ddl.KeyspaceDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,17 +50,18 @@ public class AstClient { private static final Logger logger = LoggerFactory.getLogger(AstClient.class); - private AstyanaxContext context; + private AstyanaxContext keyspaceContext; private Keyspace keyspace; private ColumnFamily EMP_CF; + private static final String KEYSPACE_NAME = "test1"; private static final String EMP_CF_NAME = "employees2"; public void init() { logger.debug("init()"); - - context = new AstyanaxContext.Builder() + + keyspaceContext = new AstyanaxContext.Builder() .forCluster("Test Cluster") - .forKeyspace("test1") + .forKeyspace(KEYSPACE_NAME) .withAstyanaxConfiguration(new AstyanaxConfigurationImpl() .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE) ) @@ -73,15 +76,54 @@ public void init() { .withConnectionPoolMonitor(new CountingConnectionPoolMonitor()) .buildKeyspace(ThriftFamilyFactory.getInstance()); - context.start(); - keyspace = context.getEntity(); - + keyspaceContext.start(); + + // Create keyspace if it doesn't already exist. + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + Keyspace ks = createKeyspaceIfNotExists(); + + keyspace = keyspaceContext.getEntity(); + EMP_CF = ColumnFamily.newColumnFamily( EMP_CF_NAME, IntegerSerializer.get(), StringSerializer.get()); + + // Create column family if it doesn't already exist. + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + createColumnFamilyIfNotExists(ks); } - + + private Keyspace createKeyspaceIfNotExists() { + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + Keyspace ks = null; + try { + ks = keyspaceContext.getClient(); + + Properties props = new Properties(); + props.setProperty("name", KEYSPACE_NAME); + props.setProperty("strategy_class", "SimpleStrategy"); + props.setProperty("strategy_options.replication_factor", "1"); + + ks.createKeyspaceIfNotExists(props); + KeyspaceDefinition ksDef = ks.describeKeyspace(); + } catch (Exception e) { + logger.info("Didn't (re)create keyspace, message={}", e.getMessage()); + } + return ks; + } + + private void createColumnFamilyIfNotExists(Keyspace ks) { + // Don't do in production; better to create from cqlsh to avoid parallel issues from eventual consistency. + if(ks != null) { + try { + ks.createColumnFamily(EMP_CF, null); + } catch (Exception e) { + // Do nothing + } + } + } + public void insert(int empId, int deptId, String firstName, String lastName) { MutationBatch m = keyspace.prepareMutationBatch(); @@ -101,10 +143,7 @@ public void insert(int empId, int deptId, String firstName, String lastName) { } logger.debug("insert ok"); } - - public void createCF() { - } - + public void read(int empId) { OperationResult> result; try { diff --git a/astyanax-queue/build.gradle b/astyanax-queue/build.gradle index 32a62d13a..22e53e171 100644 --- a/astyanax-queue/build.gradle +++ b/astyanax-queue/build.gradle @@ -1,17 +1,13 @@ apply plugin: 'osgi' +/** + * Queue implementation backed by Cassandra storage. + * Use at your own risk -- Cassandra can be a *very bad* storage engine for queues. + * If you insist on using Cassandra for queues, set a very short TTL and use DateTieredCompactionStrategy (DTCS). + */ dependencies { compile project(':astyanax-core') compile project(':astyanax-cassandra') runtime project(':astyanax-thrift') compile project(':astyanax-recipes') - compile ("com.google.guava:guava:$guavaVersion") { - force = true - } - compile "org.slf4j:slf4j-api:$slf4jVersion" - compile "commons-lang:commons-lang:$commonsLangVersion" - compile "org.codehaus.jackson:jackson-core-asl:$jacksonVersion" - compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion" - testCompile "junit:junit:$junitVersion" - testCompile project(':astyanax-thrift') } diff --git a/astyanax-queue/src/main/java/com/netflix/astyanax/recipes/queue/ShardedDistributedMessageQueue.java b/astyanax-queue/src/main/java/com/netflix/astyanax/recipes/queue/ShardedDistributedMessageQueue.java index 90c150a22..3f876ae75 100644 --- a/astyanax-queue/src/main/java/com/netflix/astyanax/recipes/queue/ShardedDistributedMessageQueue.java +++ b/astyanax-queue/src/main/java/com/netflix/astyanax/recipes/queue/ShardedDistributedMessageQueue.java @@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import org.apache.cassandra.thrift.SchemaDisagreementException; import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonParseException; @@ -424,7 +423,8 @@ String getShardKey(Message message) { /** * Return the shard for this timestamp - * @param message + * @param messageTime + * @param modShard * @return */ private String getShardKey(long messageTime, int modShard) { @@ -731,14 +731,17 @@ private void changeSchema(Callable callable) throws MessageQueueException throw new MessageQueueException("Interrupted while trying to create column family for queue " + getName(), ie); } return; - } catch (SchemaDisagreementException e) { - try { - Thread.sleep(SCHEMA_CHANGE_DELAY); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - throw new MessageQueueException("Interrupted while trying to create column family for queue " + getName(), ie); - } } catch (Exception e) { + if (e.getClass().getSimpleName().equals("SchemaDisagreementException")){ + // Check by class name since SchemaDisagreementException is defined in cassandra-thrift, + // but astayanx-cassandra should not have a Thrift-specific dependency. + try { + Thread.sleep(SCHEMA_CHANGE_DELAY); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw new MessageQueueException("Interrupted while trying to create column family for queue " + getName(), ie); + } + } if (e.getMessage().contains("already exist")) return; throw new MessageQueueException("Failed to create column family for " + queueColumnFamily.getName(), e); @@ -1032,7 +1035,7 @@ public List peekMessages(int itemsToPeek) throws MessageQueueException * Peek into messages contained in the shard. This call does not take trigger time into account * and will return messages that are not yet due to be executed * @param shardName - * @param itemsToPop + * @param itemsToPeek * @return * @throws MessageQueueException */ diff --git a/astyanax-recipes/build.gradle b/astyanax-recipes/build.gradle index 67dfa8d42..81db1448d 100644 --- a/astyanax-recipes/build.gradle +++ b/astyanax-recipes/build.gradle @@ -1,11 +1,10 @@ +/** + * Optional implementations of some common patterns. + * Use at your own risk; some of these are popular but not well-suite for Cassandra for many use cases (looking at you, AllRowsReader). + */ dependencies { - compile project(':astyanax-core') - compile project(':astyanax-cassandra') - compile ("com.google.guava:guava:$guavaVersion") { - force = true - } - compile "org.slf4j:slf4j-api:$slf4jVersion" + compile project(':astyanax-core') + compile project(':astyanax-cassandra') - testCompile "junit:junit:$junitVersion" testCompile project(':astyanax-thrift') } diff --git a/astyanax-test/build.gradle b/astyanax-test/build.gradle index 9c4454e00..714400459 100644 --- a/astyanax-test/build.gradle +++ b/astyanax-test/build.gradle @@ -1,24 +1,25 @@ apply plugin: 'osgi' +/** + * Unit/integration tests for all of Astyanax. + */ dependencies { compile project(':astyanax-core') compile project(':astyanax-cassandra') + compile project(':astyanax-thrift') compile project(':astyanax-cql') - compile project(':astyanax-contrib') - compile project(':astyanax-recipes') - compile project(':astyanax-queue') - compile project(':astyanax-entity-mapper') - compile "junit:junit:$junitVersion" - compile "joda-time:joda-time:$jodaTimeVersion" - compile "javax.persistence:persistence-api:$jpaVersion" - compile "org.slf4j:slf4j-api:$slf4jVersion" - compile "commons-lang:commons-lang:$commonsLangVersion" - compile("com.datastax.cassandra:cassandra-driver-core:$javaDriverVersion") { - exclude group: 'com.google.guava', module: 'guava' - } - compile ("org.apache.cassandra:cassandra-all:$cassandraVersion") { - force = true - } + compile project(path: ':astyanax-contrib') + compile project(path: ':astyanax-recipes') + compile project(path: ':astyanax-queue') + compile project(path: ':astyanax-entity-mapper') + compile "org.slf4j:log4j-over-slf4j:$slf4jVersion" + + // CassandraDaemon for EmbeddedCassandra + compile "org.cassandraunit:cassandra-unit-shaded:$cassandraUnitShadedVersion" + + testCompile "junit:junit:$junitVersion" + testCompile "org.slf4j:slf4j-api:$slf4jVersion" + testCompile "org.slf4j:slf4j-simple:$slf4jVersion" } diff --git a/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/SerializerPackageTests.java b/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/SerializerPackageTests.java index 09517f5c9..01bc50173 100644 --- a/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/SerializerPackageTests.java +++ b/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/SerializerPackageTests.java @@ -19,9 +19,11 @@ import java.util.ArrayList; import java.util.List; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.CompositeType; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.Serializer; +import com.netflix.astyanax.serializers.SpecificCompositeSerializer; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.CompositeType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import org.apache.log4j.Logger; import org.junit.AfterClass; import org.junit.Assert; @@ -32,7 +34,6 @@ import com.netflix.astyanax.model.ColumnFamily; import com.netflix.astyanax.model.Composite; import com.netflix.astyanax.serializers.LongSerializer; -import com.netflix.astyanax.serializers.SpecificCompositeSerializer; import com.netflix.astyanax.serializers.StringSerializer; public class SerializerPackageTests extends KeyspaceTests { @@ -84,12 +85,13 @@ public void testSerializer() throws Exception { System.out.println("ss1Result: " + ss1Result); Assert.assertEquals(ss1, ss1Result); - SpecificCompositeSerializer comp = (SpecificCompositeSerializer) serializer.getColumnNameSerializer(); - System.out.println(comp.getComparators().toString()); + Serializer comp = serializer.getColumnNameSerializer(); + System.out.println(comp.getComparatorType().toString()); Composite dc = new Composite(ss1); - List> types = new ArrayList>(); + List> types = + new ArrayList>(); types.add(UTF8Type.instance); CompositeType c1 = CompositeType.getInstance(types); diff --git a/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/utils/AstyanaxContextFactory.java b/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/utils/AstyanaxContextFactory.java index d814fdab6..3c29b0e43 100644 --- a/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/utils/AstyanaxContextFactory.java +++ b/astyanax-test/src/main/java/com/netflix/astyanax/cql/test/utils/AstyanaxContextFactory.java @@ -15,23 +15,8 @@ */ package com.netflix.astyanax.cql.test.utils; -import static com.netflix.astyanax.cql.test.utils.ClusterConfiguration.TEST_CLUSTER_NAME; -import static com.netflix.astyanax.cql.test.utils.ClusterConfiguration.TEST_KEYSPACE_NAME; -import static com.netflix.astyanax.cql.test.utils.ClusterConfiguration.TheDriver; - -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.log4j.PropertyConfigurator; - import com.datastax.driver.core.Configuration; -import com.datastax.driver.core.MetricsOptions; -import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.ProtocolOptions; -import com.datastax.driver.core.QueryOptions; -import com.datastax.driver.core.SocketOptions; -import com.datastax.driver.core.policies.Policies; import com.google.common.base.Supplier; import com.netflix.astyanax.AstyanaxContext; import com.netflix.astyanax.Cluster; @@ -43,9 +28,16 @@ import com.netflix.astyanax.connectionpool.impl.CountingConnectionPoolMonitor; import com.netflix.astyanax.cql.CqlFamilyFactory; import com.netflix.astyanax.cql.JavaDriverConnectionPoolConfigurationImpl; -import com.netflix.astyanax.cql.test.utils.ClusterConfiguration.Driver; +import com.netflix.astyanax.cql.test.utils.ClusterConfiguration.*; import com.netflix.astyanax.impl.AstyanaxConfigurationImpl; import com.netflix.astyanax.thrift.ThriftFamilyFactory; +import org.apache.log4j.PropertyConfigurator; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static com.netflix.astyanax.cql.test.utils.ClusterConfiguration.*; public class AstyanaxContextFactory { @@ -174,12 +166,9 @@ public List get() { ProtocolOptions protocolOptions = new ProtocolOptions(9042); - Configuration jdConfig = new Configuration(new Policies(), - protocolOptions, - new PoolingOptions(), - new SocketOptions(), - new MetricsOptions(), - new QueryOptions()); + Configuration jdConfig = Configuration.builder() + .withProtocolOptions(protocolOptions) + .build(); AstyanaxContext context = new AstyanaxContext.Builder() .forKeyspace(keyspaceName) diff --git a/astyanax-test/src/main/resources/cassandra2-template.yaml b/astyanax-test/src/main/resources/cassandra2-template.yaml index fe88ac21f..a14107f4c 100644 --- a/astyanax-test/src/main/resources/cassandra2-template.yaml +++ b/astyanax-test/src/main/resources/cassandra2-template.yaml @@ -28,7 +28,7 @@ seed_provider: - seeds: 127.0.0.1 concurrent_reads: 32 concurrent_writes: 64 -memtable_flush_queue_size: 4 +#memtable_flush_queue_size: 4 trickle_fsync: false trickle_fsync_interval_in_kb: 10240 storage_port: $STORAGE_PORT$ @@ -45,10 +45,10 @@ incremental_backups: false snapshot_before_compaction: false auto_snapshot: false column_index_size_in_kb: 64 -in_memory_compaction_limit_in_mb: 128 -multithreaded_compaction: false +#in_memory_compaction_limit_in_mb: 128 +#multithreaded_compaction: false compaction_throughput_mb_per_sec: 128 -compaction_preheat_key_cache: true +#compaction_preheat_key_cache: true read_request_timeout_in_ms: 10000 range_request_timeout_in_ms: 10000 write_request_timeout_in_ms: 10000 @@ -62,7 +62,7 @@ dynamic_snitch_badness_threshold: 0.1 request_scheduler: org.apache.cassandra.scheduler.NoScheduler index_interval: 256 inter_dc_tcp_nodelay: true -memtable_total_space_in_mb: 1024 +#memtable_total_space_in_mb: 1024 rpc_min_threads: 16 rpc_max_threads: 2048 stream_throughput_outbound_megabits_per_sec: '400' @@ -70,6 +70,6 @@ dynamic_snitch: true concurrent_compactors: 1 num_tokens: 1 auto_bootstrap: true -preheat_kernel_page_cache: false +#preheat_kernel_page_cache: false cas_contention_timeout_in_ms: 1000 file_cache_size_in_mb: '512' \ No newline at end of file diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/CompositeEntityManagerTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/CompositeEntityManagerTest.java index a85eab320..116e39a57 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/CompositeEntityManagerTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/CompositeEntityManagerTest.java @@ -119,7 +119,7 @@ private static void createKeyspace() throws Exception { keyspace.dropKeyspace(); } catch (Exception e) { - LOG.info(e.getMessage(), e); + LOG.info(e.getMessage()); } keyspace.createKeyspace(ImmutableMap.builder() diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/SampleEntity.java b/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/SampleEntity.java index 1ecb0d988..93cb83ea7 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/SampleEntity.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/entitystore/SampleEntity.java @@ -11,7 +11,7 @@ import javax.persistence.Entity; import javax.persistence.Id; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.codehaus.jettison.json.JSONException; diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/recipes/LockRecipeTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/recipes/LockRecipeTest.java index 89ff1a4c2..714ba19c0 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/recipes/LockRecipeTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/recipes/LockRecipeTest.java @@ -2,6 +2,7 @@ import java.util.concurrent.TimeUnit; +import com.netflix.astyanax.test.EmbeddedCassandra; import junit.framework.Assert; import org.junit.AfterClass; @@ -24,7 +25,6 @@ import com.netflix.astyanax.recipes.locks.StaleLockException; import com.netflix.astyanax.serializers.LongSerializer; import com.netflix.astyanax.serializers.StringSerializer; -import com.netflix.astyanax.test.EmbeddedCassandra; import com.netflix.astyanax.thrift.ThriftFamilyFactory; /** diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/recipes/MiscUnitTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/recipes/MiscUnitTest.java index f82f6b61d..be134bcdf 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/recipes/MiscUnitTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/recipes/MiscUnitTest.java @@ -1,27 +1,9 @@ package com.netflix.astyanax.recipes; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -import junit.framework.Assert; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.common.base.Function; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.netflix.astyanax.AstyanaxContext; import com.netflix.astyanax.ColumnListMutation; import com.netflix.astyanax.Keyspace; @@ -33,13 +15,7 @@ import com.netflix.astyanax.connectionpool.impl.CountingConnectionPoolMonitor; import com.netflix.astyanax.ddl.KeyspaceDefinition; import com.netflix.astyanax.impl.AstyanaxConfigurationImpl; -import com.netflix.astyanax.model.Column; -import com.netflix.astyanax.model.ColumnFamily; -import com.netflix.astyanax.model.ColumnList; -import com.netflix.astyanax.model.ConsistencyLevel; -import com.netflix.astyanax.model.Row; -import com.netflix.astyanax.partitioner.Murmur3Partitioner; -import com.netflix.astyanax.recipes.UUIDStringSupplier; +import com.netflix.astyanax.model.*; import com.netflix.astyanax.recipes.functions.ColumnCounterFunction; import com.netflix.astyanax.recipes.functions.RowCopierFunction; import com.netflix.astyanax.recipes.functions.RowCounterFunction; @@ -47,11 +23,7 @@ import com.netflix.astyanax.recipes.locks.ColumnPrefixDistributedRowLock; import com.netflix.astyanax.recipes.locks.StaleLockException; import com.netflix.astyanax.recipes.reader.AllRowsReader; -import com.netflix.astyanax.recipes.uniqueness.ColumnPrefixUniquenessConstraint; -import com.netflix.astyanax.recipes.uniqueness.DedicatedMultiRowUniquenessConstraint; -import com.netflix.astyanax.recipes.uniqueness.MultiRowUniquenessConstraint; -import com.netflix.astyanax.recipes.uniqueness.NotUniqueException; -import com.netflix.astyanax.recipes.uniqueness.RowUniquenessConstraint; +import com.netflix.astyanax.recipes.uniqueness.*; import com.netflix.astyanax.serializers.IntegerSerializer; import com.netflix.astyanax.serializers.LongSerializer; import com.netflix.astyanax.serializers.StringSerializer; @@ -59,6 +31,19 @@ import com.netflix.astyanax.thrift.ThriftFamilyFactory; import com.netflix.astyanax.util.SingletonEmbeddedCassandra; import com.netflix.astyanax.util.TimeUUIDUtils; +import junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; public class MiscUnitTest { private static Logger LOG = LoggerFactory.getLogger(MiscUnitTest.class); @@ -959,7 +944,7 @@ public synchronized Boolean apply(Row row) { .build(); try { - Stopwatch sw = new Stopwatch().start(); + Stopwatch sw = Stopwatch.createStarted(); boolean result = reader.call(); long runtimeMillis = sw.stop().elapsed(TimeUnit.MILLISECONDS); diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/serializers/SerializersTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/serializers/SerializersTest.java index 7cc2d87f3..5c1271b97 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/serializers/SerializersTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/serializers/SerializersTest.java @@ -9,10 +9,10 @@ import junit.framework.Assert; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.CompositeType; -import org.apache.cassandra.db.marshal.TypeParser; -import org.apache.cassandra.utils.ByteBufferUtil; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.AbstractType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.CompositeType; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.ShadedTypeParser; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.ByteBufferUtil; import org.apache.commons.lang.StringUtils; import org.junit.Test; import org.slf4j.Logger; @@ -714,7 +714,7 @@ public void testCompositeType() { String comparatorType = "CompositeType(UTF8Type,UTF8Type)"; String columnName = "(abc,1234)"; try { - AbstractType type = TypeParser.parse(comparatorType); + AbstractType type = ShadedTypeParser.parse(comparatorType); if (type instanceof CompositeType) { CompositeType ctype = (CompositeType) type; @@ -734,7 +734,7 @@ public void testCompositeType() { public void testDeserializeOfSepecificSerializer() throws Exception { Composite composite1 = new Composite("abc", 123L); CompositeSerializer serializer = new SpecificCompositeSerializer( - (CompositeType) TypeParser + (CompositeType) ShadedTypeParser .parse("CompositeType(UTF8Type,LongType)")); ByteBuffer byteBuffer = serializer.toByteBuffer(composite1); Composite composite2 = serializer.fromByteBuffer(byteBuffer); diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/thrift/CqlTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/thrift/CqlTest.java index 58bd434f0..f4412e0b8 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/thrift/CqlTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/thrift/CqlTest.java @@ -7,7 +7,7 @@ import junit.framework.Assert; -import org.apache.cassandra.db.marshal.UTF8Type; +import com.netflix.astyanax.shaded.org.apache.cassandra.db.marshal.UTF8Type; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; diff --git a/astyanax-test/src/test/java/com/netflix/astyanax/thrift/ThriftKeyspaceImplTest.java b/astyanax-test/src/test/java/com/netflix/astyanax/thrift/ThriftKeyspaceImplTest.java index b0b1f386f..0ed14c809 100644 --- a/astyanax-test/src/test/java/com/netflix/astyanax/thrift/ThriftKeyspaceImplTest.java +++ b/astyanax-test/src/test/java/com/netflix/astyanax/thrift/ThriftKeyspaceImplTest.java @@ -25,7 +25,7 @@ import junit.framework.Assert; import org.apache.cassandra.thrift.KsDef; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import org.apache.commons.lang.RandomStringUtils; import org.apache.log4j.BasicConfigurator; import org.junit.AfterClass; @@ -2219,7 +2219,7 @@ public void testGetAllKeysRoot() { Assert.assertNull(row); row = result.getResult().getRowByIndex(10); - Assert.assertEquals("M", row.getKey()); + Assert.assertEquals("K", row.getKey()); /* * LOG.info("Get " + result.getResult().size() + " keys"); for * (Row row : result.getResult()) { diff --git a/astyanax-thrift/build.gradle b/astyanax-thrift/build.gradle index 5aeefd570..3f3fc8b41 100644 --- a/astyanax-thrift/build.gradle +++ b/astyanax-thrift/build.gradle @@ -1,12 +1,13 @@ apply plugin: 'osgi' +/** + * Thrift protocol implementation of astyanax-core. + * Note Apache Cassandra 4.x+ will drop support for Thrift protocol. + * Switch to DataStax Java Driver for Apache Cassandra + * or astyanax-cql. + */ dependencies { compile project(':astyanax-core') - compile project(':astyanax-cassandra') + compile project(':astyanax-cassandra') compile "org.apache.cassandra:cassandra-thrift:$cassandraVersion" - compile ("org.apache.thrift:libthrift:$thriftVersion") { - force = true - } - - testCompile "junit:junit:$junitVersion" } diff --git a/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/ThriftAllRowsQueryImpl.java b/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/ThriftAllRowsQueryImpl.java index 2c9d81d52..a25e183e9 100644 --- a/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/ThriftAllRowsQueryImpl.java +++ b/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/ThriftAllRowsQueryImpl.java @@ -32,7 +32,7 @@ import org.apache.cassandra.thrift.SlicePredicate; import org.apache.cassandra.thrift.SliceRange; import org.apache.cassandra.thrift.Cassandra.Client; -import org.apache.cassandra.utils.Pair; +import com.netflix.astyanax.shaded.org.apache.cassandra.utils.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/model/ThriftCounterColumnListImpl.java b/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/model/ThriftCounterColumnListImpl.java index a4df86ad1..ff5abb89a 100644 --- a/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/model/ThriftCounterColumnListImpl.java +++ b/astyanax-thrift/src/main/java/com/netflix/astyanax/thrift/model/ThriftCounterColumnListImpl.java @@ -24,13 +24,14 @@ import com.netflix.astyanax.Serializer; import com.netflix.astyanax.model.AbstractColumnList; import com.netflix.astyanax.model.Column; +import org.apache.cassandra.thrift.CounterColumn; public class ThriftCounterColumnListImpl extends AbstractColumnList { - private final List columns; - private Map lookup; + private final List columns; + private Map lookup; private final Serializer colSer; - public ThriftCounterColumnListImpl(List columns, Serializer colSer) { + public ThriftCounterColumnListImpl(List columns, Serializer colSer) { this.columns = columns; this.colSer = colSer; } @@ -38,9 +39,9 @@ public ThriftCounterColumnListImpl(List> iterator() { class IteratorImpl implements Iterator> { - Iterator base; + Iterator base; - public IteratorImpl(Iterator base) { + public IteratorImpl(Iterator base) { this.base = base; } @@ -51,7 +52,7 @@ public boolean hasNext() { @Override public Column next() { - org.apache.cassandra.thrift.CounterColumn c = base.next(); + CounterColumn c = base.next(); return new ThriftCounterColumnImpl(colSer.fromBytes(c.getName()), c); } @@ -67,7 +68,7 @@ public void remove() { public Column getColumnByName(C columnName) { constructMap(); - org.apache.cassandra.thrift.CounterColumn c = lookup.get(columnName); + CounterColumn c = lookup.get(columnName); if (c == null) { return null; } @@ -76,7 +77,7 @@ public Column getColumnByName(C columnName) { @Override public Column getColumnByIndex(int idx) { - org.apache.cassandra.thrift.CounterColumn c = columns.get(idx); + CounterColumn c = columns.get(idx); return new ThriftCounterColumnImpl(colSer.fromBytes(c.getName()), c); } @@ -114,7 +115,7 @@ public Collection getColumnNames() { private void constructMap() { if (lookup == null) { lookup = Maps.newHashMap(); - for (org.apache.cassandra.thrift.CounterColumn column : columns) { + for (CounterColumn column : columns) { lookup.put(colSer.fromBytes(column.getName()), column); } } diff --git a/astyanax/build.gradle b/astyanax/build.gradle index 9a300749e..71a64a22b 100644 --- a/astyanax/build.gradle +++ b/astyanax/build.gradle @@ -1,6 +1,15 @@ +/** + * Project to add dependencies on every Astyanax module. + * + * Please don't depend on this module; it's a bad practice and exists only for backwards-compatibility. + * + * Instead add explicit dependency on only the modules you actually use, for example astyanax-thrift or astyanax-cql. + * Depending on these will automatically add any other necessary transitive dependencies. + */ dependencies { compile project(':astyanax-core') compile project(':astyanax-cassandra') + compile project(':astyanax-cassandra-all-shaded') compile project(':astyanax-thrift') compile project(':astyanax-cql') compile project(':astyanax-queue') diff --git a/build.gradle b/build.gradle index 16043724a..e0bac0b0f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,11 @@ plugins { - id 'nebula.netflixoss' version '2.2.5' + id 'nebula.netflixoss' version '4.0.1' } ext.githubProjectName = rootProject.name // Change if github project name is not the same as the root project's name apply from: 'dependency-versions.gradle' +print "Using cassandraVersion=${cassandraVersion}\n" subprojects { apply plugin: 'nebula.netflixoss' @@ -12,10 +13,14 @@ subprojects { group = "com.netflix.${githubProjectName}" - sourceCompatibility = 1.6 - targetCompatibility = 1.6 - repositories { jcenter() } + + // Don't stop the build for JavaDoc errors + javadoc{ + options { + failOnError = false + } + } } diff --git a/dependency-versions.gradle b/dependency-versions.gradle index bd0d94982..fa5d14341 100644 --- a/dependency-versions.gradle +++ b/dependency-versions.gradle @@ -1,26 +1,38 @@ ext { - cassandraVersion = "2.0.12" - thriftVersion = "0.9.2" - junitVersion = "4.8.1" - guavaVersion = "15.0" - snappyVersion = "1.1.1.6" + cassandraVersion = "2.0.17" + + // DataStax cassandra-driver-core version for astyanax-cql: + javaDriverVersion = "3.3.2" + + // EmbeddedCassandra for astyanax-test + cassandraUnitShadedVersion="2.1.9.2" + + thriftVersion = "0.10.0" + junitVersion = "4.12" + + // Depend on Guava version 19 for minimum required backwards compatibility + // but test against 20, 21, 22, 23.6-jre for forwards-compatibility to avoid forcing anyone to 19. + guavaVersion = "19.0" +// guavaVersion = "20.0" +// guavaVersion = "21.0" +// guavaVersion = "22.0" +// guavaVersion = "23.6-jre" +// guavaVersion = "24.1.1-jre" +// guavaVersion = "25.0-jre" + jacksonVersion = "1.9.13" - cassandraThriftVersion = "2.0.12" - jodaTimeVersion = "1.6.2" - highScaleLibVersion = "1.1.2" + jodaTimeVersion = "2.9.9" + highScaleLibVersion = "1.1.4" uuidVersion = "3.2" - slf4jVersion = "1.6.4" - jettisonVersion = "1.2" - commonsCodecVersion = "1.5" - commonsLangVersion = "2.4" + slf4jVersion = "1.7.25" + jettisonVersion = "1.3.8" + commonsCodecVersion = "1.10" + commonsLangVersion = "2.6" commonsCsvVersion = "1.0-r706900_3" - concurrentLinkedHashMapVersion = "1.3" - jacksonVersion = "1.9.2" - snappyVersion = "1.0.4.1" - jpaVersion = "1.0" - nettyVersion = "3.9.0.Final" - commonsIOVersion = "2.1" - javaDriverVersion = "2.0.6" - lz4Version = "1.2.0" + jpaVersion = "1.0.2" + // LZ4 version suggested by cassandra-driver-core 3.3.2: + lz4Version = "1.3.0" + // Snappy version suggested by cassandra-driver-core 3.3.2: + snappyVersion = "1.1.2.6" metricCoreVersion = "3.0.2" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c97a8bdb9..6ffa23784 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ea3c445b0..afb76609c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jan 29 15:48:55 PST 2015 +#Thu May 03 13:47:38 PDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/gradlew b/gradlew index 91a7e269e..9aa616c27 100755 --- a/gradlew +++ b/gradlew @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -161,4 +161,9 @@ function splitJvmOpts() { eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then + cd "$(dirname "$0")" +fi + exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 index aec99730b..e95643d6a --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/settings.gradle b/settings.gradle index 62c99d954..a04c21c0c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,4 @@ rootProject.name='astyanax' -include 'astyanax-core', 'astyanax-queue', 'astyanax-thrift', 'astyanax-cql', 'astyanax-recipes', 'astyanax-cassandra', 'astyanax-entity-mapper', 'astyanax-examples', 'astyanax-contrib', 'astyanax-test', 'astyanax' +include 'astyanax', 'astyanax-core', 'astyanax-cassandra', 'astyanax-cassandra-all-shaded', + 'astyanax-thrift', 'astyanax-cql', 'astyanax-recipes', 'astyanax-queue', 'astyanax-entity-mapper', + 'astyanax-contrib', 'astyanax-examples', 'astyanax-test'