From ff0d44676ef63bc607fa8bc408d91c28027a4d0b Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Wed, 19 Jul 2017 14:08:38 -0500 Subject: [PATCH 001/382] JAVA-1555: Include VIEW and CDC in WriteType --- changelog/README.md | 4 ++++ .../java/com/datastax/driver/core/WriteType.java | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/changelog/README.md b/changelog/README.md index 3320ae0f026..7079ab025bb 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,5 +1,9 @@ ## Changelog +### 3.4.0 (In progress) + +- [bug] JAVA-1555: Include VIEW and CDC in WriteType. + ### 3.3.0 - [bug] JAVA-1469: Update LoggingRetryPolicy to deal with SLF4J-353. diff --git a/driver-core/src/main/java/com/datastax/driver/core/WriteType.java b/driver-core/src/main/java/com/datastax/driver/core/WriteType.java index 80269211db9..cf4cca8a73a 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/WriteType.java +++ b/driver-core/src/main/java/com/datastax/driver/core/WriteType.java @@ -48,5 +48,15 @@ public enum WriteType { * A conditional write. If a timeout has this {@code WriteType}, the timeout has happened while doing the compare-and-swap for * an conditional update. In this case, the update may or may not have been applied. */ - CAS; + CAS, + /** + * Indicates that the timeout was related to acquiring locks needed for updating materialized + * views affected by write operation. + */ + VIEW, + /** + * Indicates that the timeout was related to acquiring space for change data capture logs for cdc + * tracked tables. + */ + CDC; } From b80f2c6ae511e257c7ffe0d2feb6f53a71417dbb Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Thu, 7 Sep 2017 16:13:37 -0500 Subject: [PATCH 002/382] Use precise distribution for java6 and 7 support Default distribution (trusty) does not support openjdk6 or oraclejdk7 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 489a813b9f1..3b8087aa084 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ jdk: - oraclejdk7 - oraclejdk8 sudo: false +dist: precise before_install: # Require JDK8 for compiling - jdk_switcher use oraclejdk8 From 1288562c4a154cb0af36aa077a0f0a865d0ccef2 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 8 Sep 2017 10:06:43 -0500 Subject: [PATCH 003/382] Update travis.yml to work with trusty distribution. Precise distribution being phased out, trusty distribution lacks openjdk6 and oraclejdk7. Replace with openjdk7. Jenkins and Appveyor builds will be used to verify jdk6 support. --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b8087aa084..0292d381cdd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,8 @@ language: java jdk: -- openjdk6 -- oraclejdk7 +- openjdk7 - oraclejdk8 sudo: false -dist: precise before_install: # Require JDK8 for compiling - jdk_switcher use oraclejdk8 From fa359a8f9cb302ea069783936aeb4dcfa9b48bab Mon Sep 17 00:00:00 2001 From: Collin Sauve Date: Fri, 22 Sep 2017 17:52:23 -0400 Subject: [PATCH 004/382] JAVA-1587: Deterministic ordering of columns used in mapper query (#864) --- changelog/README.md | 2 + .../driver/mapping/AliasedMappedProperty.java | 9 +++- .../com/datastax/driver/mapping/Mapper.java | 2 +- .../mapping/MapperSaveNullFieldsTest.java | 53 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 7079ab025bb..3439a457150 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -3,6 +3,8 @@ ### 3.4.0 (In progress) - [bug] JAVA-1555: Include VIEW and CDC in WriteType. +- [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery + ### 3.3.0 diff --git a/driver-mapping/src/main/java/com/datastax/driver/mapping/AliasedMappedProperty.java b/driver-mapping/src/main/java/com/datastax/driver/mapping/AliasedMappedProperty.java index de9a7a003b3..bcf0b9834ed 100644 --- a/driver-mapping/src/main/java/com/datastax/driver/mapping/AliasedMappedProperty.java +++ b/driver-mapping/src/main/java/com/datastax/driver/mapping/AliasedMappedProperty.java @@ -15,7 +15,7 @@ */ package com.datastax.driver.mapping; -class AliasedMappedProperty { +class AliasedMappedProperty implements Comparable { final MappedProperty mappedProperty; final String alias; @@ -25,4 +25,11 @@ class AliasedMappedProperty { this.mappedProperty = (MappedProperty) mappedProperty; this.alias = alias; } + + @Override + public int compareTo(AliasedMappedProperty that) { + String thisColName = mappedProperty.getMappedName(); + String thatColName = that.mappedProperty.getMappedName(); + return thisColName.compareTo(thatColName); + } } diff --git a/driver-mapping/src/main/java/com/datastax/driver/mapping/Mapper.java b/driver-mapping/src/main/java/com/datastax/driver/mapping/Mapper.java index 03a6cd76f85..e2c0d90a3b3 100644 --- a/driver-mapping/src/main/java/com/datastax/driver/mapping/Mapper.java +++ b/driver-mapping/src/main/java/com/datastax/driver/mapping/Mapper.java @@ -221,7 +221,7 @@ public Statement saveQuery(T entity, Option... options) { } private ListenableFuture saveQueryAsync(T entity, final EnumMap options) { - final Map columnToValue = new HashMap(); + final Map columnToValue = new TreeMap(); final boolean useUnsetForNullValue = !shouldSaveNullFields(options) && manager.protocolVersionAsInt >= 4; final boolean includeColumnsWithNullValue = shouldSaveNullFields(options) || useUnsetForNullValue; diff --git a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperSaveNullFieldsTest.java b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperSaveNullFieldsTest.java index 4b9c0bdaeed..a8a5a2ebb61 100644 --- a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperSaveNullFieldsTest.java +++ b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperSaveNullFieldsTest.java @@ -17,10 +17,15 @@ import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.CCMTestsSupport; +import com.datastax.driver.core.Session; import com.datastax.driver.core.utils.CassandraVersion; import com.datastax.driver.mapping.Mapper.Option; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import java.util.List; +import java.util.Set; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -42,6 +47,54 @@ public void setup() { mapper = new MappingManager(session()).mapper(User.class); } + /** + * ensure that queries generated between different sessions consistently generates the same prepared statement + * query for different permutations of null columns being present and saved. + * + * @jira_ticket JAVA-1587 + */ + @Test(groups = "short") + public void should_order_save_query_prepared_statement_columns_consistently() { + List> allSessionStatements = Lists.newArrayList(); + for (int i = 0; i < 5; i++) { + Session session = cluster().connect(keyspace); + Mapper userMapper = new MappingManager(session()).mapper(User.class); + + List statements = Lists.newArrayList(); + + // generate a variety of permutations of columns being present + // both present + statements.add(getQuery(userMapper, false, false, Option.saveNullFields(false))); + // neither name or phone present + statements.add(getQuery(userMapper, true, true, Option.saveNullFields(false))); + // name not present + statements.add(getQuery(userMapper, true, false, Option.saveNullFields(false))); + // phone not present + statements.add(getQuery(userMapper, false, true, Option.saveNullFields(false))); + + allSessionStatements.add(statements); + session.close(); + } + + int statementCount = allSessionStatements.iterator().next().size(); + for (int i = 0; i < statementCount; i++) { + Set uniqueStatements = Sets.newTreeSet(); + for (List statements : allSessionStatements) { + uniqueStatements.add(statements.get(i)); + } + assertThat(uniqueStatements).as("Expected only one statement permutation, must not be ordered consistently.").hasSize(1); + } + } + + private String getQuery(Mapper mapper, boolean nullName, boolean nullPhone, Option... options) { + String newName = nullName ? null : "new_name"; + String newPhone = nullPhone ? null : "new_phone"; + User newUser = new User("test_login", newName, newPhone); + + return ((BoundStatement) mapper.saveQuery(newUser, options)).preparedStatement().getQueryString(); + } + + @CassandraVersion("2.1.0") @Test(groups = "short") void should_save_null_fields_if_requested() { should_save_null_fields(true, Option.saveNullFields(true)); From 1abad4123b05ec1ca44d2ba139257dc311f6c8a4 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 22 Sep 2017 16:54:57 -0500 Subject: [PATCH 005/382] JAVA-1599: exportAsString improvements (sort, format, clustering order) (#863) JAVA-1407 improved exportAsString to ensure that user types were described in topological order. However a side effect of this change is that User Types are not always consistently ordered as it depended on undefined Map ordering behavior which may vary based on JDK implementation. While this is not a functional issue, it would be preferable that the same order were always returned. This implementation ensures this by ordering the adjacency list of a vertex by alphabetical name of the user type. If there are no dependencies between user types, the result of this change is that user types are ordered alphabetically. --- build.yaml | 2 +- changelog/README.md | 1 + .../driver/core/AbstractTableMetadata.java | 29 +-- .../driver/core/AggregateMetadata.java | 5 +- .../datastax/driver/core/DirectedGraph.java | 21 +- .../driver/core/FunctionMetadata.java | 4 +- .../driver/core/KeyspaceMetadata.java | 72 +++++- .../driver/core/MaterializedViewMetadata.java | 24 +- .../datastax/driver/core/SchemaParser.java | 20 +- .../datastax/driver/core/TableMetadata.java | 41 +++- .../com/datastax/driver/core/UserType.java | 13 +- .../driver/core/AggregateMetadataTest.java | 20 +- .../driver/core/DirectedGraphTest.java | 77 ++++-- .../driver/core/ExportAsStringTest.java | 224 ++++++++++++++++++ .../driver/core/FunctionMetadataTest.java | 31 ++- .../driver/core/UnresolvedUserTypeTest.java | 75 ++++-- .../resources/export_as_string_test_2.0.cql | 42 ++++ .../resources/export_as_string_test_2.1.cql | 64 +++++ .../resources/export_as_string_test_2.2.cql | 110 +++++++++ .../resources/export_as_string_test_3.0.cql | 173 ++++++++++++++ .../resources/export_as_string_test_3.11.cql | 179 ++++++++++++++ 21 files changed, 1104 insertions(+), 123 deletions(-) create mode 100644 driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java create mode 100644 driver-core/src/test/resources/export_as_string_test_2.0.cql create mode 100644 driver-core/src/test/resources/export_as_string_test_2.1.cql create mode 100644 driver-core/src/test/resources/export_as_string_test_2.2.cql create mode 100644 driver-core/src/test/resources/export_as_string_test_3.0.cql create mode 100644 driver-core/src/test/resources/export_as_string_test_3.11.cql diff --git a/build.yaml b/build.yaml index 956c97fe3b2..9c9e7860806 100644 --- a/build.yaml +++ b/build.yaml @@ -42,7 +42,7 @@ cassandra: - '2.1' - '2.2' - '3.0' - - '3.10' + - '3.11' build: - script: | . /usr/local/bin/jdk_switcher.sh diff --git a/changelog/README.md b/changelog/README.md index 3439a457150..a49dabc82da 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -3,6 +3,7 @@ ### 3.4.0 (In progress) - [bug] JAVA-1555: Include VIEW and CDC in WriteType. +- [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery diff --git a/driver-core/src/main/java/com/datastax/driver/core/AbstractTableMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/AbstractTableMetadata.java index ee8b9205386..e79ec65cf37 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/AbstractTableMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/AbstractTableMetadata.java @@ -33,6 +33,14 @@ public int compare(ColumnMetadata c1, ColumnMetadata c2) { } }; + // comparator for ordering tables and views by name. + static final Comparator byNameComparator = new Comparator() { + @Override + public int compare(AbstractTableMetadata o1, AbstractTableMetadata o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + static final Predicate isAscending = new Predicate() { @Override public boolean apply(ClusteringOrder o) { @@ -237,10 +245,10 @@ public String asCQLQuery() { protected StringBuilder appendOptions(StringBuilder sb, boolean formatted) { // Options - sb.append(" WITH "); + sb.append("WITH "); if (options.isCompactStorage()) and(sb.append("COMPACT STORAGE"), formatted); - if (!Iterables.all(clusteringOrder, isAscending)) + if (!clusteringOrder.isEmpty()) and(appendClusteringOrder(sb), formatted); sb.append("read_repair_chance = ").append(options.getReadRepairChance()); and(sb, formatted).append("dclocal_read_repair_chance = ").append(options.getLocalReadRepairChance()); @@ -285,7 +293,7 @@ private StringBuilder appendClusteringOrder(StringBuilder sb) { sb.append("CLUSTERING ORDER BY ("); for (int i = 0; i < clusteringColumns.size(); i++) { if (i > 0) sb.append(", "); - sb.append(clusteringColumns.get(i).getName()).append(' ').append(clusteringOrder.get(i)); + sb.append(Metadata.quoteIfNecessary(clusteringColumns.get(i).getName())).append(' ').append(clusteringOrder.get(i)); } return sb.append(')'); } @@ -310,18 +318,7 @@ private static String formatOptionMap(Map m) { } private StringBuilder and(StringBuilder sb, boolean formatted) { - return newLine(sb, formatted).append(spaces(2, formatted)).append(" AND "); - } - - static String spaces(int n, boolean formatted) { - if (!formatted) - return ""; - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < n; i++) - sb.append(' '); - - return sb.toString(); + return spaceOrNewLine(sb, formatted).append("AND "); } static StringBuilder newLine(StringBuilder sb, boolean formatted) { @@ -331,7 +328,7 @@ static StringBuilder newLine(StringBuilder sb, boolean formatted) { } static StringBuilder spaceOrNewLine(StringBuilder sb, boolean formatted) { - sb.append(formatted ? '\n' : ' '); + sb.append(formatted ? "\n " : ' '); return sb; } diff --git a/driver-core/src/main/java/com/datastax/driver/core/AggregateMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/AggregateMetadata.java index bf8e6887943..a08f624d0d7 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/AggregateMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/AggregateMetadata.java @@ -202,8 +202,9 @@ private String asCQLQuery(boolean formatted) { TableMetadata.spaceOrNewLine(sb, formatted) .append("SFUNC ") - .append(Metadata.quoteIfNecessary(stateFuncSimpleName)) - .append(" STYPE ") + .append(Metadata.quoteIfNecessary(stateFuncSimpleName)); + TableMetadata.spaceOrNewLine(sb, formatted) + .append("STYPE ") .append(stateType.asFunctionParameterString()); if (finalFuncSimpleName != null) diff --git a/driver-core/src/main/java/com/datastax/driver/core/DirectedGraph.java b/driver-core/src/main/java/com/datastax/driver/core/DirectedGraph.java index 5987c511d71..a0aa7cdca6f 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/DirectedGraph.java +++ b/driver-core/src/main/java/com/datastax/driver/core/DirectedGraph.java @@ -33,8 +33,10 @@ class DirectedGraph { final Map vertices; final Multimap adjacencyList; boolean wasSorted; + final Comparator comparator; - DirectedGraph(List vertices) { + DirectedGraph(Comparator comparator, List vertices) { + this.comparator = comparator; this.vertices = Maps.newHashMapWithExpectedSize(vertices.size()); this.adjacencyList = HashMultimap.create(); @@ -43,8 +45,8 @@ class DirectedGraph { } } - DirectedGraph(V... vertices) { - this(Arrays.asList(vertices)); + DirectedGraph(Comparator comparator, V... vertices) { + this(comparator, Arrays.asList(vertices)); } /** @@ -65,16 +67,21 @@ List topologicalSort() { Queue queue = new LinkedList(); - for (Map.Entry entry : vertices.entrySet()) { - if (entry.getValue() == 0) - queue.add(entry.getKey()); + // Sort vertices so order of evaluation is always the same (instead of depending on undefined map order behavior) + List orderedVertices = new ArrayList(vertices.keySet()); + Collections.sort(orderedVertices, comparator); + for (V v : orderedVertices) { + if (vertices.get(v) == 0) + queue.add(v); } List result = Lists.newArrayList(); while (!queue.isEmpty()) { V vertex = queue.remove(); result.add(vertex); - for (V successor : adjacencyList.get(vertex)) { + List adjacentVertices = new ArrayList(adjacencyList.get(vertex)); + Collections.sort(adjacentVertices, comparator); + for (V successor : adjacentVertices) { if (decrementAndGetCount(successor) == 0) queue.add(successor); } diff --git a/driver-core/src/main/java/com/datastax/driver/core/FunctionMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/FunctionMetadata.java index 22221728456..f229ee1d8fe 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/FunctionMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/FunctionMetadata.java @@ -174,11 +174,9 @@ private String asCQLQuery(boolean formatted) { first = false; else sb.append(','); - TableMetadata.newLine(sb, formatted); String name = entry.getKey(); DataType type = entry.getValue(); sb - .append(TableMetadata.spaces(4, formatted)) .append(Metadata.quoteIfNecessary(name)) .append(' ') .append(type.asFunctionParameterString()); @@ -190,7 +188,7 @@ private String asCQLQuery(boolean formatted) { TableMetadata.spaceOrNewLine(sb, formatted) .append("RETURNS ") - .append(returnType); + .append(returnType.asFunctionParameterString()); TableMetadata.spaceOrNewLine(sb, formatted) .append("LANGUAGE ") diff --git a/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java index 45ce2977dbf..d827cd9fffd 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java @@ -16,6 +16,7 @@ package com.datastax.driver.core; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Lists; import java.util.*; @@ -243,6 +244,29 @@ AggregateMetadata removeAggregate(String fullName) { return aggregates.remove(fullName); } + // comparators for ordering types in cqlsh output. + + private static final Comparator typeByName = new Comparator() { + @Override + public int compare(UserType o1, UserType o2) { + return o1.getTypeName().compareTo(o2.getTypeName()); + } + }; + + private static final Comparator functionByName = new Comparator() { + @Override + public int compare(FunctionMetadata o1, FunctionMetadata o2) { + return o1.getSimpleName().compareTo(o2.getSimpleName()); + } + }; + + private static final Comparator aggregateByName = new Comparator() { + @Override + public int compare(AggregateMetadata o1, AggregateMetadata o2) { + return o1.getSimpleName().compareTo(o2.getSimpleName()); + } + }; + /** * Returns a {@code String} containing CQL queries representing this * keyspace and the user types and tables it contains. @@ -262,21 +286,61 @@ public String exportAsString() { sb.append(asCQLQuery()).append('\n'); - for (UserType udt : userTypes.values()) + // include types, tables, views, functions and aggregates, each ordered by name, with one small exception + // being that user types are ordered topologically and then by name within same level. + for (UserType udt : getSortedUserTypes()) sb.append('\n').append(udt.exportAsString()).append('\n'); - for (TableMetadata tm : tables.values()) + for (AbstractTableMetadata tm : ImmutableSortedSet.orderedBy(AbstractTableMetadata.byNameComparator).addAll(tables.values()).build()) sb.append('\n').append(tm.exportAsString()).append('\n'); - for (FunctionMetadata fm : functions.values()) + for (FunctionMetadata fm : ImmutableSortedSet.orderedBy(functionByName).addAll(functions.values()).build()) sb.append('\n').append(fm.exportAsString()).append('\n'); - for (AggregateMetadata am : aggregates.values()) + for (AggregateMetadata am : ImmutableSortedSet.orderedBy(aggregateByName).addAll(aggregates.values()).build()) sb.append('\n').append(am.exportAsString()).append('\n'); return sb.toString(); } + private List getSortedUserTypes() { + // rebuilds dependency tree of user types so they may be sorted within each dependency level. + List unsortedTypes = new ArrayList(userTypes.values()); + DirectedGraph graph = new DirectedGraph(typeByName, unsortedTypes); + for (UserType from : unsortedTypes) { + for (UserType to : unsortedTypes) { + if (from != to && dependsOn(to, from)) + graph.addEdge(from, to); + } + } + return graph.topologicalSort(); + } + + private boolean dependsOn(UserType udt1, UserType udt2) { + for (String fieldName : udt1.getFieldNames()) { + DataType fieldType = udt1.getFieldType(fieldName); + if (references(fieldType, udt2)) + return true; + } + return false; + } + + private boolean references(DataType dataType, DataType udtType) { + if (dataType.equals(udtType)) + return true; + for (DataType arg : dataType.getTypeArguments()) { + if (references(arg, udtType)) + return true; + } + if (dataType instanceof TupleType) { + for (DataType arg : ((TupleType) dataType).getComponentTypes()) { + if (references(arg, udtType)) + return true; + } + } + return false; + } + /** * Returns a CQL query representing this keyspace. *

diff --git a/driver-core/src/main/java/com/datastax/driver/core/MaterializedViewMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/MaterializedViewMetadata.java index e232e248083..f5d102d0424 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/MaterializedViewMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/MaterializedViewMetadata.java @@ -162,34 +162,32 @@ protected String asCQLQuery(boolean formatted) { StringBuilder sb = new StringBuilder(); sb.append("CREATE MATERIALIZED VIEW ") .append(keyspaceName).append('.').append(viewName) - .append(" AS "); - newLine(sb, formatted); + .append(" AS"); // SELECT - sb.append("SELECT "); + spaceOrNewLine(sb, formatted).append("SELECT "); if (includeAllColumns) { - sb.append(" * "); + sb.append("*"); } else { Iterator it = columns.values().iterator(); while (it.hasNext()) { ColumnMetadata column = it.next(); - sb.append(spaces(4, formatted)).append(Metadata.quoteIfNecessary(column.getName())); - if (it.hasNext()) sb.append(","); - sb.append(" "); - newLine(sb, formatted); + sb.append(Metadata.quoteIfNecessary(column.getName())); + if (it.hasNext()) sb.append(", "); } } // FROM - newLine(sb.append("FROM ").append(keyspaceName).append('.').append(baseTableName).append(" "), formatted); + spaceOrNewLine(sb, formatted).append("FROM ").append(keyspaceName).append('.').append(baseTableName); // WHERE // the CQL grammar allows missing WHERE clauses, although C* currently disallows it - if (whereClause != null && !whereClause.isEmpty()) - newLine(sb.append("WHERE ").append(whereClause).append(' '), formatted); + if (whereClause != null && !whereClause.isEmpty()) { + spaceOrNewLine(sb, formatted).append("WHERE ").append(whereClause); + } // PK - sb.append("PRIMARY KEY ("); + spaceOrNewLine(sb, formatted).append("PRIMARY KEY ("); if (partitionKey.size() == 1) { sb.append(Metadata.quoteIfNecessary(partitionKey.get(0).getName())); } else { @@ -208,6 +206,8 @@ protected String asCQLQuery(boolean formatted) { sb.append(", ").append(Metadata.quoteIfNecessary(cm.getName())); sb.append(')'); + // append 3 extra spaces if formatted to align WITH. + spaceOrNewLine(sb, formatted); appendOptions(sb, formatted); return sb.toString(); diff --git a/driver-core/src/main/java/com/datastax/driver/core/SchemaParser.java b/driver-core/src/main/java/com/datastax/driver/core/SchemaParser.java index 09ea0e33037..e43e4dcac57 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/SchemaParser.java +++ b/driver-core/src/main/java/com/datastax/driver/core/SchemaParser.java @@ -663,6 +663,24 @@ else if (targetType == AGGREGATE) return whereClause; } + // Used by maybeSortUdts to sort at each dependency group alphabetically. + private static final Comparator sortByTypeName = new Comparator() { + @Override + public int compare(Row o1, Row o2) { + String type1 = o1.getString(UserType.TYPE_NAME); + String type2 = o2.getString(UserType.TYPE_NAME); + + if (type1 == null && type2 == null) { + return 0; + } else if (type2 == null) { + return 1; + } else if (type1 == null) { + return -1; + } else { + return type1.compareTo(type2); + } + } + }; @Override protected List maybeSortUdts(List udtRows, Cluster cluster, String keyspace) { @@ -671,7 +689,7 @@ protected List maybeSortUdts(List udtRows, Cluster cluster, String key // For C* 3+, user-defined type resolution must be done in proper order // to guarantee that nested UDTs get resolved - DirectedGraph graph = new DirectedGraph(udtRows); + DirectedGraph graph = new DirectedGraph(sortByTypeName, udtRows); for (Row from : udtRows) { for (Row to : udtRows) { if (from != to && dependsOn(to, from, cluster, keyspace)) diff --git a/driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java index c8d133b0833..6cde2b5959d 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java @@ -16,6 +16,7 @@ package com.datastax.driver.core; import com.datastax.driver.core.utils.MoreObjects; +import com.google.common.collect.ImmutableSortedSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -384,12 +385,30 @@ public String exportAsString() { sb.append(super.exportAsString()); - for (IndexMetadata index : indexes.values()) { - sb.append('\n').append(index.asCQLQuery()); + if (!indexes.isEmpty()) { + sb.append('\n'); + + Iterator indexIt = indexes.values().iterator(); + while (indexIt.hasNext()) { + IndexMetadata index = indexIt.next(); + sb.append('\n').append(index.asCQLQuery()); + if (indexIt.hasNext()) { + sb.append('\n'); + } + } } - for (MaterializedViewMetadata view : views.values()) { - sb.append('\n').append(view.asCQLQuery()); + if (!views.isEmpty()) { + sb.append('\n'); + + Iterator viewsIt = ImmutableSortedSet.orderedBy(AbstractTableMetadata.byNameComparator).addAll(views.values()).build().iterator(); + while (viewsIt.hasNext()) { + AbstractTableMetadata view = viewsIt.next(); + sb.append('\n').append(view.exportAsString()); + if (viewsIt.hasNext()) { + sb.append('\n'); + } + } } return sb.toString(); @@ -399,12 +418,16 @@ public String exportAsString() { protected String asCQLQuery(boolean formatted) { StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE ").append(Metadata.quoteIfNecessary(keyspace.getName())).append('.').append(Metadata.quoteIfNecessary(name)).append(" ("); - newLine(sb, formatted); - for (ColumnMetadata cm : columns.values()) - newLine(sb.append(spaces(4, formatted)).append(cm).append(',').append(spaces(1, !formatted)), formatted); + if (formatted) { + spaceOrNewLine(sb, true); + } + for (ColumnMetadata cm : columns.values()) { + sb.append(cm).append(','); + spaceOrNewLine(sb, formatted); + } // PK - sb.append(spaces(4, formatted)).append("PRIMARY KEY ("); + sb.append("PRIMARY KEY ("); if (partitionKey.size() == 1) { sb.append(Metadata.quoteIfNecessary(partitionKey.get(0).getName())); } else { @@ -425,7 +448,7 @@ protected String asCQLQuery(boolean formatted) { newLine(sb, formatted); // end PK - sb.append(")"); + sb.append(") "); appendOptions(sb, formatted); return sb.toString(); } diff --git a/driver-core/src/main/java/com/datastax/driver/core/UserType.java b/driver-core/src/main/java/com/datastax/driver/core/UserType.java index 25142374c8c..fc2d8457ff4 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/UserType.java +++ b/driver-core/src/main/java/com/datastax/driver/core/UserType.java @@ -278,12 +278,17 @@ private String asCQLQuery(boolean formatted) { StringBuilder sb = new StringBuilder(); sb.append("CREATE TYPE ").append(Metadata.quoteIfNecessary(keyspace)).append('.').append(Metadata.quoteIfNecessary(typeName)).append(" ("); - TableMetadata.newLine(sb, formatted); + if (formatted) { + TableMetadata.spaceOrNewLine(sb, true); + } for (int i = 0; i < byIdx.length; i++) { - sb.append(TableMetadata.spaces(4, formatted)).append(byIdx[i]); - if (i < byIdx.length - 1) + sb.append(byIdx[i]); + if (i < byIdx.length - 1) { sb.append(','); - TableMetadata.newLine(sb, formatted); + TableMetadata.spaceOrNewLine(sb, formatted); + } else { + TableMetadata.newLine(sb, formatted); + } } return sb.append(");").toString(); diff --git a/driver-core/src/test/java/com/datastax/driver/core/AggregateMetadataTest.java b/driver-core/src/test/java/com/datastax/driver/core/AggregateMetadataTest.java index 6dbdde7abaf..d567b777580 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/AggregateMetadataTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/AggregateMetadataTest.java @@ -51,8 +51,9 @@ public void should_parse_and_format_aggregate_with_initcond_and_no_finalfunc() { assertThat(aggregate.getStateType()).isEqualTo(text()); assertThat(aggregate.toString()).isEqualTo(cqlAggregate); assertThat(aggregate.exportAsString()).isEqualTo(String.format("CREATE AGGREGATE %s.cat_tos(int)\n" - + "SFUNC cat STYPE text\n" - + "INITCOND '0';", this.keyspace)); + + " SFUNC cat\n" + + " STYPE text\n" + + " INITCOND '0';", this.keyspace)); } @Test(groups = "short") @@ -78,8 +79,9 @@ public void should_parse_and_format_aggregate_with_no_arguments() { assertThat(aggregate.getStateType()).isEqualTo(cint()); assertThat(aggregate.toString()).isEqualTo(cqlAggregate); assertThat(aggregate.exportAsString()).isEqualTo(String.format("CREATE AGGREGATE %s.mycount()\n" - + "SFUNC inc STYPE int\n" - + "INITCOND 0;", this.keyspace)); + + " SFUNC inc\n" + + " STYPE int\n" + + " INITCOND 0;", this.keyspace)); } @Test(groups = "short") @@ -108,9 +110,10 @@ public void should_parse_and_format_aggregate_with_final_function() { assertThat(aggregate.getStateType()).isEqualTo(cint()); assertThat(aggregate.toString()).isEqualTo(cqlAggregate); assertThat(aggregate.exportAsString()).isEqualTo(String.format("CREATE AGGREGATE %s.prettysum(int)\n" - + "SFUNC plus STYPE int\n" - + "FINALFUNC announce\n" - + "INITCOND 0;", this.keyspace)); + + " SFUNC plus\n" + + " STYPE int\n" + + " FINALFUNC announce\n" + + " INITCOND 0;", this.keyspace)); } @Test(groups = "short") @@ -136,7 +139,8 @@ public void should_parse_and_format_aggregate_with_no_initcond() { assertThat(aggregate.getStateType()).isEqualTo(cint()); assertThat(aggregate.toString()).isEqualTo(cqlAggregate); assertThat(aggregate.exportAsString()).isEqualTo(String.format("CREATE AGGREGATE %s.sum(int)\n" - + "SFUNC plus2 STYPE int;", this.keyspace)); + + " SFUNC plus2\n" + + " STYPE int;", this.keyspace)); } @Test(groups = "short") diff --git a/driver-core/src/test/java/com/datastax/driver/core/DirectedGraphTest.java b/driver-core/src/test/java/com/datastax/driver/core/DirectedGraphTest.java index 65d713ccd55..9341d99a12d 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/DirectedGraphTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/DirectedGraphTest.java @@ -16,22 +16,31 @@ package com.datastax.driver.core; import com.datastax.driver.core.exceptions.DriverInternalError; -import org.testng.annotations.Test; - +import java.util.Comparator; import java.util.List; +import org.testng.annotations.Test; import static org.assertj.core.api.Assertions.assertThat; public class DirectedGraphTest { + + private Comparator alphaComparator = new Comparator() { + + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }; + @Test(groups = "unit") public void should_sort_empty_graph() { - DirectedGraph g = new DirectedGraph(); + DirectedGraph g = new DirectedGraph(alphaComparator); assertThat(g.topologicalSort()).isEmpty(); } @Test(groups = "unit") public void should_sort_graph_with_one_node() { - DirectedGraph g = new DirectedGraph("A"); + DirectedGraph g = new DirectedGraph(alphaComparator, "A"); assertThat(g.topologicalSort()) .containsExactly("A"); } @@ -47,7 +56,7 @@ public void should_sort_complex_graph() { // B C // | // A - DirectedGraph g = new DirectedGraph("A", "B", "C", "D", "E", "F", "G", "H"); + DirectedGraph g = new DirectedGraph(alphaComparator, "A", "B", "C", "D", "E", "F", "G", "H"); g.addEdge("H", "F"); g.addEdge("G", "E"); g.addEdge("H", "D"); @@ -58,24 +67,54 @@ public void should_sort_complex_graph() { g.addEdge("D", "B"); g.addEdge("B", "A"); - // Topological sort order should be : GH,FE,D,CB,A - // There's no guarantee on the order within the same level, so we use sublists: + // Topological sort order should be : GH,E,F,D,BC,A List sorted = g.topologicalSort(); - assertThat(sorted.subList(0, 2)) - .contains("G", "H"); - assertThat(sorted.subList(2, 4)) - .contains("F", "E"); - assertThat(sorted.subList(4, 5)) - .contains("D"); - assertThat(sorted.subList(5, 7)) - .contains("C", "B"); - assertThat(sorted.subList(7, 8)) - .contains("A"); + assertThat(sorted).containsExactly("G", "H", "E", "F", "D", "B", "C", "A"); + } + + @Test(groups = "unit") + public void should_sort_complex_custom_comparator() { + // Version of should_sort_complex_graph using a custom comparator based on ordering largest values first. + // This is counter to how hashmaps should usually behave, so this should help ensure that the comparator is + // being used. + Comparator highFirst = new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2 - o1; + } + }; + + // sort graph and use a alphaComparator that favors larger values ordered first. + // 7 6 + // / \ /\ + // 5 | 10 + // \ / / + // 9 / + // / \/ + // 1 2 + // | + // 0 + DirectedGraph g = new DirectedGraph(highFirst, 0, 1, 2, 9, 10, 5, 6, 7); + g.addEdge(7, 5); + g.addEdge(6, 10); + g.addEdge(7, 9); + g.addEdge(5, 9); + g.addEdge(6, 9); + g.addEdge(9, 2); + g.addEdge(10, 2); + g.addEdge(9, 1); + g.addEdge(1, 0); + + // Topological sort order should be : [7,6],[5],[10],[9],[2,1],[0] + // 5 comes before 10 even though they appear at the same depth. This happens because 5's (7) dependency + // is evaluated before 10's (6), so it is placed first. + List sorted = g.topologicalSort(); + assertThat(sorted).containsExactly(7, 6, 5, 10, 9, 2, 1, 0); } @Test(groups = "unit", expectedExceptions = DriverInternalError.class) public void should_fail_to_sort_if_graph_has_a_cycle() { - DirectedGraph g = new DirectedGraph("A", "B", "C"); + DirectedGraph g = new DirectedGraph(alphaComparator, "A", "B", "C"); g.addEdge("A", "B"); g.addEdge("B", "C"); g.addEdge("C", "B"); @@ -85,7 +124,7 @@ public void should_fail_to_sort_if_graph_has_a_cycle() { @Test(groups = "unit", expectedExceptions = DriverInternalError.class) public void should_fail_to_sort_if_graph_is_a_cycle() { - DirectedGraph g = new DirectedGraph("A", "B", "C"); + DirectedGraph g = new DirectedGraph(alphaComparator, "A", "B", "C"); g.addEdge("A", "B"); g.addEdge("B", "C"); g.addEdge("C", "A"); diff --git a/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java new file mode 100644 index 00000000000..7ebb9e36aef --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import com.datastax.driver.core.schemabuilder.SchemaBuilder; +import com.datastax.driver.core.utils.CassandraVersion; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.ByteStreams; +import com.google.common.io.Closer; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +@CassandraVersion("2.0") +@CCMConfig(config = "enable_user_defined_functions:true") +public class ExportAsStringTest extends CCMTestsSupport { + + private static final Logger logger = LoggerFactory.getLogger(ExportAsStringTest.class); + + /** + * Creates a keyspace using a variety of features and ensures {@link KeyspaceMetadata#exportAsString()} + * contains the expected data in the expected order. This is not exhaustive, but covers quite a bit of different + * scenarios (materialized views, aggregates, functions, nested UDTs, etc.). + *

+ * The test also verifies that the generated schema is the same whether the keyspace and its schema was created + * during the lifecycle of the cluster or before connecting. + *

+ * Note that this test might be fragile in the future if default option values change in cassandra. In order to + * deal with new features, we create a schema for each tested C* version, and if one is not present the test + * is failed. + */ + @Test(groups = "short") + public void create_schema_and_ensure_exported_cql_is_as_expected() { + String keyspace = "complex_ks"; + Map replicationOptions = ImmutableMap.of("class", "SimpleStrategy", "replication_factor", 1); + + // create keyspace + session().execute(SchemaBuilder.createKeyspace(keyspace).with().replication(replicationOptions)); + + // create session from this keyspace. + Session session = cluster().connect(keyspace); + + KeyspaceMetadata ks; + + // udts require 2.1+ + if (ccm().getCassandraVersion().compareTo(VersionNumber.parse("2.1")) >= 0) { + // Usertype 'ztype' with two columns. Given name to ensure that even though it has an alphabetically + // later name, it shows up before other user types ('ctype') that depend on it. + session.execute(SchemaBuilder.createType("ztype") + .addColumn("c", DataType.text()).addColumn("a", DataType.cint())); + + // Usertype 'xtype' with two columns. At same level as 'ztype' since both are depended on by ctype, should + // show up before 'ztype' because it's alphabetically before, even though it was created after. + session.execute(SchemaBuilder.createType("xtype") + .addColumn("d", DataType.text())); + + ks = cluster().getMetadata().getKeyspace(keyspace); + + // Usertype 'ctype' which depends on both ztype and xtype, therefore ztype and xtype should show up earlier. + session.execute(SchemaBuilder.createType("ctype") + .addColumn("z", ks.getUserType("ztype").copy(true)) + .addColumn("x", ks.getUserType("xtype").copy(true))); + + // Usertype 'btype' which has no dependencies, should show up before 'xtype' and 'ztype' since it's + // alphabetically before. + session.execute(SchemaBuilder.createType("btype").addColumn("a", DataType.text())); + + // Refetch keyspace for < 3.0 schema this is required as a new keyspace metadata reference may be created. + ks = cluster().getMetadata().getKeyspace(keyspace); + + // Usertype 'atype' which depends on 'ctype', so should show up after 'ctype', 'xtype' and 'ztype'. + session.execute(SchemaBuilder.createType("atype") + .addColumn("c", ks.getUserType("ctype").copy(true))); + + // A simple table with a udt column and LCS compaction strategy. + session.execute(SchemaBuilder.createTable("ztable") + .addPartitionKey("zkey", DataType.text()) + .addColumn("a", ks.getUserType("atype").copy(true)) + .withOptions().compactionOptions(SchemaBuilder.leveledStrategy().ssTableSizeInMB(95))); + } else { + // A simple table with LCS compaction strategy. + session.execute(SchemaBuilder.createTable("ztable") + .addPartitionKey("zkey", DataType.text()) + .addColumn("a", DataType.cint()) + .withOptions().compactionOptions(SchemaBuilder.leveledStrategy().ssTableSizeInMB(95))); + } + + // date type requries 2.2+ + if (ccm().getCassandraVersion().compareTo(VersionNumber.parse("2.2")) >= 0) { + // A table that will have materialized views (copied from mv docs) + session.execute(SchemaBuilder.createTable("cyclist_mv").addPartitionKey("cid", DataType.uuid()) + .addColumn("name", DataType.text()) + .addColumn("age", DataType.cint()) + .addColumn("birthday", DataType.date()) + .addColumn("country", DataType.text())); + + // index on table with view, index should be printed first. + session.execute(SchemaBuilder.createIndex("cyclist_by_country") + .onTable("cyclist_mv") + .andColumn("country")); + + // materialized views require 3.0+ + if (ccm().getCassandraVersion().compareTo(VersionNumber.parse("3.0")) >= 0) { + // A materialized view for cyclist_mv, reverse clustering. created first to ensure creation order does not + // matter, alphabetical does. + session.execute("CREATE MATERIALIZED VIEW cyclist_by_r_age " + + "AS SELECT age, birthday, name, country " + + "FROM cyclist_mv " + + "WHERE age IS NOT NULL AND cid IS NOT NULL " + + "PRIMARY KEY (age, cid) " + + "WITH CLUSTERING ORDER BY (cid DESC)" + ); + + // A materialized view for cyclist_mv, select * + session.execute("CREATE MATERIALIZED VIEW cyclist_by_a_age " + + "AS SELECT * " + + "FROM cyclist_mv " + + "WHERE age IS NOT NULL AND cid IS NOT NULL " + + "PRIMARY KEY (age, cid)"); + + // A materialized view for cyclist_mv, select columns + session.execute("CREATE MATERIALIZED VIEW cyclist_by_age " + + "AS SELECT age, birthday, name, country " + + "FROM cyclist_mv " + + "WHERE age IS NOT NULL AND cid IS NOT NULL " + + "PRIMARY KEY (age, cid) WITH comment = 'simple view'"); + } + } + + // A table with a secondary index, taken from documentation on secondary index. + session.execute(SchemaBuilder.createTable("rank_by_year_and_name") + .addPartitionKey("race_year", DataType.cint()) + .addPartitionKey("race_name", DataType.text()) + .addClusteringColumn("rank", DataType.cint()) + .addColumn("cyclist_name", DataType.text())); + + session.execute(SchemaBuilder.createIndex("ryear") + .onTable("rank_by_year_and_name") + .andColumn("race_year")); + + session.execute(SchemaBuilder.createIndex("rrank") + .onTable("rank_by_year_and_name") + .andColumn("rank")); + + // udfs and udas require 2.22+ + if (ccm().getCassandraVersion().compareTo(VersionNumber.parse("2.2")) >= 0) { + // UDFs + session.execute("CREATE OR REPLACE FUNCTION avgState ( state tuple, val int ) CALLED ON NULL INPUT RETURNS tuple LANGUAGE java AS \n" + + " 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;';"); + session.execute("CREATE OR REPLACE FUNCTION avgFinal ( state tuple ) CALLED ON NULL INPUT RETURNS double LANGUAGE java AS \n" + + " 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);';"); + + // UDAs + session.execute("CREATE AGGREGATE IF NOT EXISTS mean ( int ) \n" + + "SFUNC avgState STYPE tuple FINALFUNC avgFinal INITCOND (0,0);"); + session.execute("CREATE AGGREGATE IF NOT EXISTS average ( int ) \n" + + "SFUNC avgState STYPE tuple FINALFUNC avgFinal INITCOND (0,0);"); + } + + ks = cluster().getMetadata().getKeyspace(keyspace); + + // validate that the exported schema matches what was expected exactly. + assertThat(ks.exportAsString().trim()).isEqualTo(getExpectedCqlString()); + + // Also validate that when you create a Cluster with schema already created that the exported string + // is the same. + Cluster newCluster = this.createClusterBuilderNoDebouncing() + .addContactPointsWithPorts(this.getContactPointsWithPorts()) + .build(); + try { + newCluster.init(); + ks = newCluster.getMetadata().getKeyspace(keyspace); + assertThat(ks.exportAsString().trim()).isEqualTo(getExpectedCqlString()); + } finally { + newCluster.close(); + } + } + + private String getExpectedCqlString() { + String majorMinor = ccm().getCassandraVersion().getMajor() + "." + ccm().getCassandraVersion().getMinor(); + String resourceName = "/export_as_string_test_" + majorMinor + ".cql"; + + Closer closer = Closer.create(); + try { + InputStream is = ExportAsStringTest.class.getResourceAsStream(resourceName); + closer.register(is); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + ByteStreams.copy(is, ps); + return baos.toString().trim(); + } catch (IOException e) { + logger.warn("Failure to read {}", resourceName, e); + fail("Unable to read " + resourceName + " is it defined?"); + } finally { + try { + closer.close(); + } catch (IOException e) { // no op + logger.warn("Failure closing streams", e); + } + } + return ""; + } +} diff --git a/driver-core/src/test/java/com/datastax/driver/core/FunctionMetadataTest.java b/driver-core/src/test/java/com/datastax/driver/core/FunctionMetadataTest.java index 83aee5a348c..317103ae37e 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/FunctionMetadataTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/FunctionMetadataTest.java @@ -50,13 +50,11 @@ public void should_parse_and_format_simple_function() { assertThat(function.toString()) .isEqualTo(cql); assertThat(function.exportAsString()) - .isEqualTo(String.format("CREATE FUNCTION %s.plus(\n" - + " s int,\n" - + " v int)\n" - + "RETURNS NULL ON NULL INPUT\n" - + "RETURNS int\n" - + "LANGUAGE java\n" - + "AS 'return s+v;';", this.keyspace)); + .isEqualTo(String.format("CREATE FUNCTION %s.plus(s int,v int)\n" + + " RETURNS NULL ON NULL INPUT\n" + + " RETURNS int\n" + + " LANGUAGE java\n" + + " AS 'return s+v;';", this.keyspace)); } @Test(groups = "short") @@ -81,10 +79,10 @@ public void should_parse_and_format_function_with_no_arguments() { .isEqualTo(cql); assertThat(function.exportAsString()) .isEqualTo(String.format("CREATE FUNCTION %s.pi()\n" - + "CALLED ON NULL INPUT\n" - + "RETURNS double\n" - + "LANGUAGE java\n" - + "AS 'return Math.PI;';", this.keyspace)); + + " CALLED ON NULL INPUT\n" + + " RETURNS double\n" + + " LANGUAGE java\n" + + " AS 'return Math.PI;';", this.keyspace)); } @Test(groups = "short") @@ -154,12 +152,11 @@ public void should_parse_and_format_functions_with_complex_arguments() { assertThat(function.toString()) .isEqualTo(cql); assertThat(function.exportAsString()) - .isEqualTo(String.format("CREATE FUNCTION %s.complex(\n" - + " x tuple, map>)\n" - + "RETURNS NULL ON NULL INPUT\n" - + "RETURNS int\n" - + "LANGUAGE java\n" - + "AS 'return 42;';", this.keyspace)); + .isEqualTo(String.format("CREATE FUNCTION %s.complex(x tuple, map>)\n" + + " RETURNS NULL ON NULL INPUT\n" + + " RETURNS int\n" + + " LANGUAGE java\n" + + " AS 'return 42;';", this.keyspace)); } @Override diff --git a/driver-core/src/test/java/com/datastax/driver/core/UnresolvedUserTypeTest.java b/driver-core/src/test/java/com/datastax/driver/core/UnresolvedUserTypeTest.java index d721d61c9fd..ba7ae18e2da 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/UnresolvedUserTypeTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/UnresolvedUserTypeTest.java @@ -16,18 +16,57 @@ package com.datastax.driver.core; import com.datastax.driver.core.utils.CassandraVersion; -import org.testng.annotations.Test; - import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; +import org.testng.annotations.Test; import static com.datastax.driver.core.Assertions.assertThat; -import static com.datastax.driver.core.DataType.*; +import static com.datastax.driver.core.DataType.cint; +import static com.datastax.driver.core.DataType.list; +import static com.datastax.driver.core.DataType.map; +import static com.datastax.driver.core.DataType.set; @CassandraVersion("3.0") public class UnresolvedUserTypeTest extends CCMTestsSupport { + private static final String KEYSPACE = "unresolved_user_type_test"; + + private static final String EXPECTED_SCHEMA = String.format("CREATE KEYSPACE %s WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true;\n" + + "\n" + + "CREATE TYPE %s.g (\n" + + " f1 int\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.h (\n" + + " f1 int\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"E\" (\n" + + " f1 frozen>>\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"F\" (\n" + + " f1 frozen<%s.h>\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"D\" (\n" + + " f1 frozen>\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"B\" (\n" + + " f1 frozen>>\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"C\" (\n" + + " f1 frozen, frozen<%s.\"D\">>>\n" + + ");\n" + + "\n" + + "CREATE TYPE %s.\"A\" (\n" + + " f1 frozen<%s.\"C\">\n" + + ");\n", KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, + KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE, KEYSPACE); + @Override public void onTestContextInitialized() { execute( @@ -45,16 +84,17 @@ Creates the following acyclic graph (edges directed upwards | A - Topological sort order should be : GH,FE,D,CB,A + Topological sort order should be : gh,FE,D,CB,A */ - String.format("CREATE TYPE %s.h (f1 int)", keyspace), - String.format("CREATE TYPE %s.g (f1 int)", keyspace), - String.format("CREATE TYPE %s.\"F\" (f1 frozen)", keyspace), - String.format("CREATE TYPE %s.\"E\" (f1 frozen>)", keyspace), - String.format("CREATE TYPE %s.\"D\" (f1 frozen>)", keyspace), - String.format("CREATE TYPE %s.\"C\" (f1 frozen>)", keyspace), - String.format("CREATE TYPE %s.\"B\" (f1 frozen>)", keyspace), - String.format("CREATE TYPE %s.\"A\" (f1 frozen<\"C\">)", keyspace) + "CREATE KEYSPACE unresolved_user_type_test WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}", + String.format("CREATE TYPE %s.h (f1 int)", KEYSPACE), + String.format("CREATE TYPE %s.g (f1 int)", KEYSPACE), + String.format("CREATE TYPE %s.\"F\" (f1 frozen)", KEYSPACE), + String.format("CREATE TYPE %s.\"E\" (f1 frozen>)", KEYSPACE), + String.format("CREATE TYPE %s.\"D\" (f1 frozen>)", KEYSPACE), + String.format("CREATE TYPE %s.\"C\" (f1 frozen>)", KEYSPACE), + String.format("CREATE TYPE %s.\"B\" (f1 frozen>)", KEYSPACE), + String.format("CREATE TYPE %s.\"A\" (f1 frozen<\"C\">)", KEYSPACE) ); } @@ -75,7 +115,7 @@ public void should_resolve_nested_user_types() throws ExecutionException, Interr } private void checkUserTypes(Metadata metadata) { - KeyspaceMetadata keyspaceMetadata = metadata.getKeyspace(keyspace); + KeyspaceMetadata keyspaceMetadata = metadata.getKeyspace(KEYSPACE); UserType a = keyspaceMetadata.getUserType("\"A\""); UserType b = keyspaceMetadata.getUserType("\"B\""); @@ -106,12 +146,7 @@ private void checkUserTypes(Metadata metadata) { String script = keyspaceMetadata.exportAsString(); - assertThat(script.indexOf(a.exportAsString())).isGreaterThan(script.indexOf(b.exportAsString())).isGreaterThan(script.indexOf(c.exportAsString())); - assertThat(script.indexOf(b.exportAsString())).isGreaterThan(script.indexOf(d.exportAsString())); - assertThat(script.indexOf(c.exportAsString())).isGreaterThan(script.indexOf(d.exportAsString())); - assertThat(script.indexOf(d.exportAsString())).isGreaterThan(script.indexOf(e.exportAsString())).isGreaterThan(script.indexOf(f.exportAsString())); - assertThat(script.indexOf(e.exportAsString())).isGreaterThan(script.indexOf(g.exportAsString())).isGreaterThan(script.indexOf(h.exportAsString())); - assertThat(script.indexOf(f.exportAsString())).isGreaterThan(script.indexOf(g.exportAsString())).isGreaterThan(script.indexOf(h.exportAsString())); - + // validate against a strict expectation that the schema is exactly as defined. + assertThat(script).isEqualTo(EXPECTED_SCHEMA); } } diff --git a/driver-core/src/test/resources/export_as_string_test_2.0.cql b/driver-core/src/test/resources/export_as_string_test_2.0.cql new file mode 100644 index 00000000000..8da26460927 --- /dev/null +++ b/driver-core/src/test/resources/export_as_string_test_2.0.cql @@ -0,0 +1,42 @@ +CREATE KEYSPACE complex_ks WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true; + +CREATE TABLE complex_ks.rank_by_year_and_name ( + race_year int, + race_name text, + rank int, + cyclist_name text, + PRIMARY KEY ((race_year, race_name), rank) +) WITH CLUSTERING ORDER BY (rank ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND replicate_on_write = true + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = 'KEYS_ONLY' + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND index_interval = 128; + +CREATE INDEX rrank ON complex_ks.rank_by_year_and_name (rank); + +CREATE INDEX ryear ON complex_ks.rank_by_year_and_name (race_year); + +CREATE TABLE complex_ks.ztable ( + zkey text, + a int, + PRIMARY KEY (zkey) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND replicate_on_write = true + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.1 + AND caching = 'KEYS_ONLY' + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 95 } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND index_interval = 128; diff --git a/driver-core/src/test/resources/export_as_string_test_2.1.cql b/driver-core/src/test/resources/export_as_string_test_2.1.cql new file mode 100644 index 00000000000..0d71991cd70 --- /dev/null +++ b/driver-core/src/test/resources/export_as_string_test_2.1.cql @@ -0,0 +1,64 @@ +CREATE KEYSPACE complex_ks WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true; + +CREATE TYPE complex_ks.btype ( + a text +); + +CREATE TYPE complex_ks.xtype ( + d text +); + +CREATE TYPE complex_ks.ztype ( + c text, + a int +); + +CREATE TYPE complex_ks.ctype ( + z frozen, + x frozen +); + +CREATE TYPE complex_ks.atype ( + c frozen +); + +CREATE TABLE complex_ks.rank_by_year_and_name ( + race_year int, + race_name text, + rank int, + cyclist_name text, + PRIMARY KEY ((race_year, race_name), rank) +) WITH CLUSTERING ORDER BY (rank ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048; + +CREATE INDEX rrank ON complex_ks.rank_by_year_and_name (rank); + +CREATE INDEX ryear ON complex_ks.rank_by_year_and_name (race_year); + +CREATE TABLE complex_ks.ztable ( + zkey text, + a frozen, + PRIMARY KEY (zkey) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.1 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 95 } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048; diff --git a/driver-core/src/test/resources/export_as_string_test_2.2.cql b/driver-core/src/test/resources/export_as_string_test_2.2.cql new file mode 100644 index 00000000000..2789c7ce999 --- /dev/null +++ b/driver-core/src/test/resources/export_as_string_test_2.2.cql @@ -0,0 +1,110 @@ +CREATE KEYSPACE complex_ks WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true; + +CREATE TYPE complex_ks.btype ( + a text +); + +CREATE TYPE complex_ks.xtype ( + d text +); + +CREATE TYPE complex_ks.ztype ( + c text, + a int +); + +CREATE TYPE complex_ks.ctype ( + z frozen, + x frozen +); + +CREATE TYPE complex_ks.atype ( + c frozen +); + +CREATE TABLE complex_ks.cyclist_mv ( + cid uuid, + age int, + birthday date, + country text, + name text, + PRIMARY KEY (cid) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048; + +CREATE INDEX cyclist_by_country ON complex_ks.cyclist_mv (country); + +CREATE TABLE complex_ks.rank_by_year_and_name ( + race_year int, + race_name text, + rank int, + cyclist_name text, + PRIMARY KEY ((race_year, race_name), rank) +) WITH CLUSTERING ORDER BY (rank ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048; + +CREATE INDEX rrank ON complex_ks.rank_by_year_and_name (rank); + +CREATE INDEX ryear ON complex_ks.rank_by_year_and_name (race_year); + +CREATE TABLE complex_ks.ztable ( + zkey text, + a frozen, + PRIMARY KEY (zkey) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.1 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 95 } + AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99.0PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048; + +CREATE FUNCTION complex_ks.avgfinal(state tuple) + CALLED ON NULL INPUT + RETURNS double + LANGUAGE java + AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; + +CREATE FUNCTION complex_ks.avgstate(state tuple,val int) + CALLED ON NULL INPUT + RETURNS tuple + LANGUAGE java + AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; + +CREATE AGGREGATE complex_ks.average(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); + +CREATE AGGREGATE complex_ks.mean(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); diff --git a/driver-core/src/test/resources/export_as_string_test_3.0.cql b/driver-core/src/test/resources/export_as_string_test_3.0.cql new file mode 100644 index 00000000000..04fe39adc98 --- /dev/null +++ b/driver-core/src/test/resources/export_as_string_test_3.0.cql @@ -0,0 +1,173 @@ +CREATE KEYSPACE complex_ks WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true; + +CREATE TYPE complex_ks.btype ( + a text +); + +CREATE TYPE complex_ks.xtype ( + d text +); + +CREATE TYPE complex_ks.ztype ( + c text, + a int +); + +CREATE TYPE complex_ks.ctype ( + z frozen, + x frozen +); + +CREATE TYPE complex_ks.atype ( + c frozen +); + +CREATE TABLE complex_ks.cyclist_mv ( + cid uuid, + age int, + birthday date, + country text, + name text, + PRIMARY KEY (cid) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE INDEX cyclist_by_country ON complex_ks.cyclist_mv (country); + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_a_age AS + SELECT * + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_age AS + SELECT age, cid, birthday, country, name + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = 'simple view' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_r_age AS + SELECT age, cid, birthday, country, name + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid DESC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE TABLE complex_ks.rank_by_year_and_name ( + race_year int, + race_name text, + rank int, + cyclist_name text, + PRIMARY KEY ((race_year, race_name), rank) +) WITH CLUSTERING ORDER BY (rank ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE INDEX rrank ON complex_ks.rank_by_year_and_name (rank); + +CREATE INDEX ryear ON complex_ks.rank_by_year_and_name (race_year); + +CREATE TABLE complex_ks.ztable ( + zkey text, + a frozen, + PRIMARY KEY (zkey) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.1 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 95 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0; + +CREATE FUNCTION complex_ks.avgfinal(state tuple) + CALLED ON NULL INPUT + RETURNS double + LANGUAGE java + AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; + +CREATE FUNCTION complex_ks.avgstate(state tuple,val int) + CALLED ON NULL INPUT + RETURNS tuple + LANGUAGE java + AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; + +CREATE AGGREGATE complex_ks.average(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); + +CREATE AGGREGATE complex_ks.mean(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); diff --git a/driver-core/src/test/resources/export_as_string_test_3.11.cql b/driver-core/src/test/resources/export_as_string_test_3.11.cql new file mode 100644 index 00000000000..204d1c58f68 --- /dev/null +++ b/driver-core/src/test/resources/export_as_string_test_3.11.cql @@ -0,0 +1,179 @@ +CREATE KEYSPACE complex_ks WITH REPLICATION = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1' } AND DURABLE_WRITES = true; + +CREATE TYPE complex_ks.btype ( + a text +); + +CREATE TYPE complex_ks.xtype ( + d text +); + +CREATE TYPE complex_ks.ztype ( + c text, + a int +); + +CREATE TYPE complex_ks.ctype ( + z frozen, + x frozen +); + +CREATE TYPE complex_ks.atype ( + c frozen +); + +CREATE TABLE complex_ks.cyclist_mv ( + cid uuid, + age int, + birthday date, + country text, + name text, + PRIMARY KEY (cid) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE INDEX cyclist_by_country ON complex_ks.cyclist_mv (country); + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_a_age AS + SELECT * + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_age AS + SELECT age, cid, birthday, country, name + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = 'simple view' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE MATERIALIZED VIEW complex_ks.cyclist_by_r_age AS + SELECT age, cid, birthday, country, name + FROM complex_ks.cyclist_mv + WHERE age IS NOT NULL AND cid IS NOT NULL + PRIMARY KEY (age, cid) + WITH CLUSTERING ORDER BY (cid DESC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE TABLE complex_ks.rank_by_year_and_name ( + race_year int, + race_name text, + rank int, + cyclist_name text, + PRIMARY KEY ((race_year, race_name), rank) +) WITH CLUSTERING ORDER BY (rank ASC) + AND read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.01 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold' : 32, 'min_threshold' : 4 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE INDEX rrank ON complex_ks.rank_by_year_and_name (rank); + +CREATE INDEX ryear ON complex_ks.rank_by_year_and_name (race_year); + +CREATE TABLE complex_ks.ztable ( + zkey text, + a frozen, + PRIMARY KEY (zkey) +) WITH read_repair_chance = 0.0 + AND dclocal_read_repair_chance = 0.1 + AND gc_grace_seconds = 864000 + AND bloom_filter_fp_chance = 0.1 + AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' } + AND comment = '' + AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 95 } + AND compression = { 'chunk_length_in_kb' : 64, 'class' : 'org.apache.cassandra.io.compress.LZ4Compressor' } + AND default_time_to_live = 0 + AND speculative_retry = '99PERCENTILE' + AND min_index_interval = 128 + AND max_index_interval = 2048 + AND crc_check_chance = 1.0 + AND cdc = false; + +CREATE FUNCTION complex_ks.avgfinal(state tuple) + CALLED ON NULL INPUT + RETURNS double + LANGUAGE java + AS 'double r = 0; if (state.getInt(0) == 0) return null; r = state.getLong(1); r /= state.getInt(0); return Double.valueOf(r);'; + +CREATE FUNCTION complex_ks.avgstate(state tuple,val int) + CALLED ON NULL INPUT + RETURNS tuple + LANGUAGE java + AS 'if (val !=null) { state.setInt(0, state.getInt(0)+1); state.setLong(1, state.getLong(1)+val.intValue()); } return state;'; + +CREATE AGGREGATE complex_ks.average(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); + +CREATE AGGREGATE complex_ks.mean(int) + SFUNC avgstate + STYPE tuple + FINALFUNC avgfinal + INITCOND (0,0); From cc07b43aa59f670dd439ecd59826e9b3929271f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Figui=C3=A8re?= Date: Fri, 22 Sep 2017 17:31:25 -0700 Subject: [PATCH 006/382] JAVA-1500: Add a metric to report number of in-flight requests (#858) --- changelog/README.md | 1 + .../com/datastax/driver/core/Metrics.java | 19 ++++ .../driver/core/MetricsInFlightTest.java | 97 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java diff --git a/changelog/README.md b/changelog/README.md index a49dabc82da..e86a2118b09 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -5,6 +5,7 @@ - [bug] JAVA-1555: Include VIEW and CDC in WriteType. - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery +- [improvement] JAVA-1500: Add a metric to report number of in-flight requests. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/Metrics.java b/driver-core/src/main/java/com/datastax/driver/core/Metrics.java index 1debeb4a6e9..3087634dd10 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Metrics.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Metrics.java @@ -79,6 +79,16 @@ public Integer getValue() { return value; } }); + private final Gauge inFlightRequests = registry.register("inflight-requests", new Gauge() { + @Override + public Integer getValue() { + int value = 0; + for (SessionManager session : manager.sessions) + for (HostConnectionPool pool : session.pools.values()) + value += pool.totalInFlight.get(); + return value; + } + }); private final Gauge executorQueueDepth; private final Gauge blockingExecutorQueueDepth; @@ -218,6 +228,15 @@ public Gauge getTrashedConnections() { return trashedConnections; } + /** + * Returns the total number of in flight requests to Cassandra hosts. + * + * @return The total number of in flight requests to Cassandra hosts. + */ + public Gauge getInFlightRequests() { + return inFlightRequests; + } + /** * Returns the number of queued up tasks in the {@link ThreadingOptions#createExecutor(String) main internal executor}. *

diff --git a/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java b/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java new file mode 100644 index 00000000000..91c4085414b --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java @@ -0,0 +1,97 @@ +package com.datastax.driver.core; + +import org.scassandra.Scassandra; +import org.scassandra.http.client.PrimingRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +import static com.datastax.driver.core.TestUtils.nonQuietClusterCloseOptions; +import static org.scassandra.http.client.PrimingRequest.then; + +public class MetricsInFlightTest { + private ScassandraCluster sCluster; + + @BeforeMethod(groups = "short") + public void setUp() { + sCluster = ScassandraCluster.builder().withNodes(1).build(); + sCluster.init(); + } + + @AfterMethod(groups = "short") + public void tearDown() { + clearActivityLog(); + sCluster.stop(); + } + + public void clearActivityLog() { + for (Scassandra node : sCluster.nodes()) { + node.activityClient().clearAllRecordedActivity(); + } + } + + public Cluster.Builder builder() { + //Note: nonQuietClusterCloseOptions is used to speed up tests + return Cluster.builder() + .addContactPoints(sCluster.address(1).getAddress()) + .withPort(sCluster.getBinaryPort()).withNettyOptions(nonQuietClusterCloseOptions); + } + + @Test(groups = "short") + public void should_count_inflight_requests_metrics() { + sCluster.node(1).primingClient().prime(PrimingRequest.queryBuilder() + .withQuery("mock query") + .withThen(then().withFixedDelay(100000L)) + .build() + ); + + Cluster cluster = null; + try { + cluster = builder().build(); + Session session = cluster.connect(); + + assertThat(cluster.getMetrics().getInFlightRequests().getValue()).isEqualTo(0); + session.executeAsync("mock query"); + session.executeAsync("mock query"); + assertThat(cluster.getMetrics().getInFlightRequests().getValue()).isEqualTo(2); + + } finally { + if (cluster != null) { + cluster.close(); + } + } + } + + + @Test(groups = "short") + public void should_countdown_inflight_requests_metrics() { + sCluster.node(1).primingClient().prime(PrimingRequest.queryBuilder() + .withQuery("mock query") + .withThen(then()) + .build() + ); + + Cluster cluster = null; + try { + cluster = builder().build(); + Session session = cluster.connect(); + + assertThat(cluster.getMetrics().getInFlightRequests().getValue()).isEqualTo(0); + session.executeAsync("mock query").getUninterruptibly(); + session.executeAsync("mock query").getUninterruptibly(); + assertThat(cluster.getMetrics().getInFlightRequests().getValue()).isEqualTo(0); + + } finally { + if (cluster != null) { + cluster.close(); + } + } + } + +} From 271b6e29e59b00fc5551c2046f36a765ac69ede5 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Mon, 25 Sep 2017 12:52:25 -0500 Subject: [PATCH 007/382] Add license header --- .../datastax/driver/core/MetricsInFlightTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java b/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java index 91c4085414b..91298a7a48f 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/MetricsInFlightTest.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; import org.scassandra.Scassandra; From 6f9631729cad19d08bdbfef2dcf189358bda723e Mon Sep 17 00:00:00 2001 From: Evan Zeimet Date: Mon, 25 Sep 2017 15:47:28 -0500 Subject: [PATCH 008/382] JAVA-1438: QueryBuilder check for empty orderings (#832) --- changelog/README.md | 1 + .../java/com/datastax/driver/core/querybuilder/Select.java | 3 +++ .../driver/core/querybuilder/QueryBuilderTest.java | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/changelog/README.md b/changelog/README.md index e86a2118b09..c915521b974 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -6,6 +6,7 @@ - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery - [improvement] JAVA-1500: Add a metric to report number of in-flight requests. +- [bug] JAVA-1438: QueryBuilder check for empty orderings. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Select.java b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Select.java index d070a04888c..510afe17848 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Select.java +++ b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Select.java @@ -154,6 +154,9 @@ public Select orderBy(Ordering... orderings) { if (this.orderings != null) throw new IllegalStateException("An ORDER BY clause has already been provided"); + if (orderings.length == 0) + throw new IllegalArgumentException("Invalid ORDER BY argument, the orderings must not be empty."); + this.orderings = Arrays.asList(orderings); for (Ordering ordering : orderings) checkForBindMarkers(ordering); diff --git a/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java b/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java index 176be7abccb..91cf75b4243 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java @@ -165,6 +165,13 @@ public void selectTest() throws Exception { assertEquals(e.getMessage(), "An ORDER BY clause has already been provided"); } + try { + select().from("foo").orderBy(); + fail("Expected an IllegalArgumentException"); + } catch (IllegalArgumentException e) { + assertEquals(e.getMessage(), "Invalid ORDER BY argument, the orderings must not be empty."); + } + try { select().column("a").all().from("foo"); fail("Expected an IllegalStateException"); From a0d8b5695c34579802b4054fd2fa00871a095f7a Mon Sep 17 00:00:00 2001 From: Chris Lohfink Date: Fri, 30 Jun 2017 11:03:44 -0500 Subject: [PATCH 009/382] JAVA-1490: Allow zero delay for speculative executions --- changelog/README.md | 1 + .../datastax/driver/core/RequestHandler.java | 22 ++++++--- .../ConstantSpeculativeExecutionPolicy.java | 8 +-- .../policies/SpeculativeExecutionPolicy.java | 4 +- .../driver/core/SpeculativeExecutionTest.java | 49 +++++++++++++++++++ 5 files changed, 73 insertions(+), 11 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index c915521b974..e8b1516d875 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -7,6 +7,7 @@ - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery - [improvement] JAVA-1500: Add a metric to report number of in-flight requests. - [bug] JAVA-1438: QueryBuilder check for empty orderings. +- [improvement] JAVA-1490: Allow zero delay for speculative executions. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java index 27cdf129610..49f0869fdf0 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java +++ b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java @@ -119,30 +119,40 @@ private void startNewExecution() { } private void scheduleExecution(long delayMillis) { - if (isDone.get() || delayMillis <= 0) + if (isDone.get() || delayMillis < 0) return; if (logger.isTraceEnabled()) logger.trace("[{}] Schedule next speculative execution in {} ms", id, delayMillis); - scheduledExecutions.add(scheduler.newTimeout(newExecutionTask, delayMillis, TimeUnit.MILLISECONDS)); + if(delayMillis == 0) { + // kick off request immediately + scheduleExecutionImmediately(); + } else { + scheduledExecutions.add(scheduler.newTimeout(newExecutionTask, delayMillis, TimeUnit.MILLISECONDS)); + } } private final TimerTask newExecutionTask = new TimerTask() { @Override public void run(final Timeout timeout) throws Exception { scheduledExecutions.remove(timeout); - if (!isDone.get()) + if (!isDone.get()) { // We're on the timer thread so reschedule to another executor manager.executor().execute(new Runnable() { @Override public void run() { - if (metricsEnabled()) - metrics().getErrorMetrics().getSpeculativeExecutions().inc(); - startNewExecution(); + scheduleExecutionImmediately(); } }); + } } }; + private void scheduleExecutionImmediately() { + if (metricsEnabled()) + metrics().getErrorMetrics().getSpeculativeExecutions().inc(); + startNewExecution(); + } + private void cancelPendingExecutions(SpeculativeExecution ignore) { for (SpeculativeExecution execution : runningExecutions) if (execution != ignore) // not vital but this produces nicer logs diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.java index af22fcae30e..a7d1acf91fc 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.java @@ -32,13 +32,15 @@ public class ConstantSpeculativeExecutionPolicy implements SpeculativeExecutionP /** * Builds a new instance. * - * @param constantDelayMillis the delay between each speculative execution. Must be strictly positive. + * @param constantDelayMillis the delay between each speculative execution. Must be >= 0. A zero delay means + * it should immediately send `maxSpeculativeExecutions` requests along with the + * original request. * @param maxSpeculativeExecutions the number of speculative executions. Must be strictly positive. * @throws IllegalArgumentException if one of the arguments does not respect the preconditions above. */ public ConstantSpeculativeExecutionPolicy(final long constantDelayMillis, final int maxSpeculativeExecutions) { - Preconditions.checkArgument(constantDelayMillis > 0, - "delay must be strictly positive (was %d)", constantDelayMillis); + Preconditions.checkArgument(constantDelayMillis >= 0, + "delay must be >= 0 (was %d)", constantDelayMillis); Preconditions.checkArgument(maxSpeculativeExecutions > 0, "number of speculative executions must be strictly positive (was %d)", maxSpeculativeExecutions); this.constantDelayMillis = constantDelayMillis; diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.java index f936ca78c5c..35c38fb431b 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.java @@ -64,8 +64,8 @@ interface SpeculativeExecutionPlan { * Returns the time before the next speculative query. * * @param lastQueried the host that was just queried. - * @return the time (in milliseconds) before a speculative query is sent to the next host. If zero or negative, - * no speculative query will be sent. + * @return the time (in milliseconds) before a speculative query is sent to the next host. If negative, + * no speculative query will be sent. If zero it will immediately send the execution. */ long nextExecution(Host lastQueried); } diff --git a/driver-core/src/test/java/com/datastax/driver/core/SpeculativeExecutionTest.java b/driver-core/src/test/java/com/datastax/driver/core/SpeculativeExecutionTest.java index 02f5f043292..cdb2265df48 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/SpeculativeExecutionTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/SpeculativeExecutionTest.java @@ -167,6 +167,55 @@ public void should_start_speculative_execution_if_first_execution_takes_too_long assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(1); } + @Test(groups = "short") + public void should_start_speculative_execution_on_multiple_hosts_with_zero_delay() { + Cluster cluster = Cluster.builder() + .addContactPoints(scassandras.address(2).getAddress()) + .withPort(scassandras.getBinaryPort()) + .withLoadBalancingPolicy(loadBalancingPolicy) + .withSpeculativeExecutionPolicy(new ConstantSpeculativeExecutionPolicy(0, 2)) + .withQueryOptions(new QueryOptions().setDefaultIdempotence(true)) + .withRetryPolicy(new CustomRetryPolicy()) + .withNettyOptions(nonQuietClusterCloseOptions) + .build(); + Session session = cluster.connect(); + host1 = TestUtils.findHost(cluster, 1); + host2 = TestUtils.findHost(cluster, 2); + host3 = TestUtils.findHost(cluster, 3); + errors = cluster.getMetrics().getErrorMetrics(); + + scassandras.node(1).primingClient().prime(PrimingRequest.queryBuilder() + .withQuery("mock query") + .withThen(then().withRows(row("result", "result1")).withFixedDelay(1000L)) + .build() + ); + + scassandras.node(2).primingClient().prime(PrimingRequest.queryBuilder() + .withQuery("mock query") + .withThen(then().withRows(row("result", "result2")).withFixedDelay(1000L)) + .build() + ); + + scassandras.node(3).primingClient().prime(PrimingRequest.queryBuilder() + .withQuery("mock query") + .withThen(then().withRows(row("result", "result3"))) + .build() + ); + long execStartCount = errors.getSpeculativeExecutions().getCount(); + + ResultSet rs = session.execute("mock query"); + Row row = rs.one(); + + assertThat(row.getString("result")).isEqualTo("result3"); + assertThat(errors.getSpeculativeExecutions().getCount()).isEqualTo(execStartCount + 2); + ExecutionInfo executionInfo = rs.getExecutionInfo(); + // triedHosts does not contain host1 because the request to it had not completed yet + assertThat(executionInfo.getTriedHosts()).containsOnly(host3); + assertThat(executionInfo.getQueriedHost()).isEqualTo(host3); + assertThat(executionInfo.getSpeculativeExecutions()).isEqualTo(2); + assertThat(executionInfo.getSuccessfulExecutionIndex()).isEqualTo(2); + } + @Test(groups = "short") public void should_wait_until_all_executions_have_finished() { // Rely on read timeouts to trigger errors that cause an execution to move to the next node From 07d81db7e729e69783e100f76dde306b6c026e4a Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 18 Aug 2017 16:11:58 -0500 Subject: [PATCH 010/382] JAVA-1607: Add FAQ entry for netty-transport-native-epoll --- changelog/README.md | 1 + faq/README.md | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/changelog/README.md b/changelog/README.md index e8b1516d875..8fe019aa958 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -8,6 +8,7 @@ - [improvement] JAVA-1500: Add a metric to report number of in-flight requests. - [bug] JAVA-1438: QueryBuilder check for empty orderings. - [improvement] JAVA-1490: Allow zero delay for speculative executions. +- [documentation] JAVA-1607: Add FAQ entry for netty-transport-native-epoll. ### 3.3.0 diff --git a/faq/README.md b/faq/README.md index 60a62864f7d..abd221933a1 100644 --- a/faq/README.md +++ b/faq/README.md @@ -236,6 +236,28 @@ before submitting the next batch. See the [Acquisition queue] section of the Pooling section in the manual for explanation of how the driver enqueues requests when connections are over-utilized. +### What is Netty's native epoll transport and how do I enable or disable it? + +Netty provides [native transport libraries](http://netty.io/wiki/native-transports.html) which generally generate less +garbage and improve performance when compared to the default NIO-based transport. +By default if the driver detects the `netty-transport-native-epoll` library in its classpath it will attempt to use +[`EpollEventLoopGroup`](https://netty.io/4.0/api/io/netty/channel/epoll/EpollEventLoopGroup.html) for its underlying +event loop. + +In the usual case this works fine in linux environments. On the other hand, many users have run into compatibility +issues when the version of `netty-transport-native-epoll` is not compatible with a version of Netty in an application's +classpath. One such case is where an application depends on a version of `netty-all` that is different than the +version of `netty-handler` that the driver depends on. In such a case, a user may encounter an exception such as the +one described in [JAVA-1535](https://datastax-oss.atlassian.net/browse/JAVA-1535). + +While the epoll transport may in general improve performance, we expect the improvement to be marginal for a lot of use +cases. Therefore, if you don't want `netty-transport-native-epoll` to be used by the driver even if the library is +present in an application's classpath, the most direct way to disable this is to provide the system property value +`-Dcom.datastax.driver.FORCE_NIO=true` to your application to force the use of the default Netty NIO-based event loop. +If properly used, the following log message will be logged at INFO on startup: + +> Found Netty's native epoll transport in the classpath, but NIO was forced through the FORCE_NIO system property. + [Blobs.java]: https://github.com/datastax/java-driver/tree/3.3.0/driver-examples/src/main/java/com/datastax/driver/examples/datatypes/Blobs.java [CASSANDRA-7304]: https://issues.apache.org/jira/browse/CASSANDRA-7304 [Parameters and Binding]: ../manual/statements/prepared/#parameters-and-binding From de3c0c664c52485cad3a428818945599283d43f5 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Tue, 29 Aug 2017 14:19:35 +0200 Subject: [PATCH 011/382] JAVA-1613: Fix broken shaded Netty detection in NettyUtil The shading detection fails when another (non shaded) netty is in the class path (which is the main reason for shading). --- changelog/README.md | 1 + .../com/datastax/driver/core/NettyUtil.java | 20 ++---- driver-tests/pom.xml | 1 + driver-tests/shading/pom.xml | 47 ++++++++++++++ driver-tests/shading/shaded/pom.xml | 65 +++++++++++++++++++ .../com/datastax/driver/core/NettyUtilIT.java | 28 ++++++++ driver-tests/shading/unshaded/pom.xml | 48 ++++++++++++++ .../com/datastax/driver/core/NettyUtilIT.java | 28 ++++++++ pom.xml | 7 ++ 9 files changed, 230 insertions(+), 15 deletions(-) create mode 100644 driver-tests/shading/pom.xml create mode 100644 driver-tests/shading/shaded/pom.xml create mode 100644 driver-tests/shading/shaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java create mode 100644 driver-tests/shading/unshaded/pom.xml create mode 100644 driver-tests/shading/unshaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java diff --git a/changelog/README.md b/changelog/README.md index 8fe019aa958..aed66789a7f 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -29,6 +29,7 @@ - [improvement] JAVA-1488: Upgrade Netty to 4.0.47.Final. - [improvement] JAVA-1460: Add speculative execution number to ExecutionInfo - [improvement] JAVA-1431: Improve error handling during pool initialization. +- [bug] JAVA-1613: Fix broken shaded Netty detection in NettyUtil. ### 3.2.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/NettyUtil.java b/driver-core/src/main/java/com/datastax/driver/core/NettyUtil.java index 66ac351395c..c35e0d9fc3a 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/NettyUtil.java +++ b/driver-core/src/main/java/com/datastax/driver/core/NettyUtil.java @@ -37,7 +37,6 @@ class NettyUtil { private static final Logger LOGGER = LoggerFactory.getLogger(NettyUtil.class); - private static final boolean SHADED; private static final boolean USE_EPOLL; @@ -47,21 +46,12 @@ class NettyUtil { private static final Class[] EVENT_GROUP_ARGUMENTS = {int.class, ThreadFactory.class}; + private static final String SHADING_DETECTION_STRING = "io.netty.shadingdetection.ShadingDetection"; + + private static final boolean SHADED = !SHADING_DETECTION_STRING.equals(String.format("%s.%s.shadingdetection.ShadingDetection", "io", "netty")); + static { - boolean shaded; - try { - // prevent this string from being shaded - Class.forName(String.format("%s.%s.channel.Channel", "io", "netty")); - shaded = false; - } catch (ClassNotFoundException e) { - try { - Class.forName("com.datastax.shaded.netty.channel.Channel"); - shaded = true; - } catch (ClassNotFoundException e1) { - throw new AssertionError("Cannot locate Netty classes in the classpath:" + e1); - } - } - SHADED = shaded; + boolean useEpoll = false; if (!SHADED) { try { diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 8c3b59037d8..1a79b393cc3 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -33,6 +33,7 @@ stress osgi + shading diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml new file mode 100644 index 00000000000..98b0f0d47f0 --- /dev/null +++ b/driver-tests/shading/pom.xml @@ -0,0 +1,47 @@ + + + + 4.0.0 + + + com.datastax.cassandra + cassandra-driver-tests-parent + 3.4.0-SNAPSHOT + + + pom + cassandra-driver-tests-shading + DataStax Java Driver for Apache Cassandra Tests - Shading + A test project for tests which ensure that the shading of the driver didn't break anything. + + + shaded + unshaded + + + + + org.testng + testng + test + + + + + diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml new file mode 100644 index 00000000000..e3e9be9aa8b --- /dev/null +++ b/driver-tests/shading/shaded/pom.xml @@ -0,0 +1,65 @@ + + + + 4.0.0 + + + com.datastax.cassandra + cassandra-driver-tests-shading + 3.4.0-SNAPSHOT + + + cassandra-driver-tests-shading-shaded + DataStax Java Driver for Apache Cassandra Tests - Shading - Shaded + The shading detection tests for the shaded driver + + + + + com.datastax.cassandra + cassandra-driver-core + shaded + + + * + io.netty + + + + + + + io.netty + netty-handler + test + + + + org.testng + testng + test + + + + + + diff --git a/driver-tests/shading/shaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java b/driver-tests/shading/shaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java new file mode 100644 index 00000000000..c31de86c032 --- /dev/null +++ b/driver-tests/shading/shaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class NettyUtilIT { + + @Test(groups = "unit") + public void should_detect_shaded_driver() { + Assert.assertTrue(NettyUtil.isShaded()); + } + +} diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml new file mode 100644 index 00000000000..1985767b273 --- /dev/null +++ b/driver-tests/shading/unshaded/pom.xml @@ -0,0 +1,48 @@ + + + + 4.0.0 + + + com.datastax.cassandra + cassandra-driver-tests-shading + 3.4.0-SNAPSHOT + + + cassandra-driver-tests-shading-unshaded + DataStax Java Driver for Apache Cassandra Tests - Shading - Unshaded + The shading detection tests for the unshaded driver + + + + + com.datastax.cassandra + cassandra-driver-core + + + + org.testng + testng + test + + + + + + diff --git a/driver-tests/shading/unshaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java b/driver-tests/shading/unshaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java new file mode 100644 index 00000000000..ef1e77d81fc --- /dev/null +++ b/driver-tests/shading/unshaded/src/test/java/com/datastax/driver/core/NettyUtilIT.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class NettyUtilIT { + + @Test(groups = "unit") + public void should_detect_non_shaded_driver() { + Assert.assertFalse(NettyUtil.isShaded()); + } + +} diff --git a/pom.xml b/pom.xml index 897867bfa5a..d364e879a98 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,13 @@ ${project.parent.version} + + com.datastax.cassandra + cassandra-driver-core + ${project.parent.version} + shaded + + com.datastax.cassandra cassandra-driver-core From 831f5a22de655e1c2336dd9a9131ab8cbbeea16f Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 26 Sep 2017 09:18:08 -0700 Subject: [PATCH 012/382] JAVA-1630: Fix Metadata.addIfAbsent --- changelog/README.md | 1 + .../com/datastax/driver/core/Cluster.java | 26 +++++++++---------- .../driver/core/ControlConnection.java | 6 ++--- .../com/datastax/driver/core/Metadata.java | 10 +++---- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index aed66789a7f..6a280752383 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -9,6 +9,7 @@ - [bug] JAVA-1438: QueryBuilder check for empty orderings. - [improvement] JAVA-1490: Allow zero delay for speculative executions. - [documentation] JAVA-1607: Add FAQ entry for netty-transport-native-epoll. +- [bug] JAVA-1630: Fix Metadata.addIfAbsent. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java index 56b17601649..ce4cb89dfd4 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java @@ -1505,7 +1505,7 @@ long delayMs() { // We don't want to signal -- call onAdd() -- because nothing is ready // yet (loadbalancing policy, control connection, ...). All we want is // create the Host object so we can initialize the control connection. - metadata.add(address); + metadata.addIfAbsent(metadata.newHost(address)); } Collection allHosts = metadata.allHosts(); @@ -2714,27 +2714,25 @@ public ListenableFuture deliver(List events) { case UP: Host upHost = metadata.getHost(address); if (upHost == null) { - upHost = metadata.add(address); - // If upHost is still null, it means we didn't know about it the line before but - // got beaten at adding it to the metadata by another thread. In that case, it's - // fine to let the other thread win and ignore the notification here - if (upHost == null) + upHost = metadata.newHost(address); + Host previous = metadata.addIfAbsent(upHost); + if (previous != null) { + // We got beat by another thread at adding the host. Let it win and ignore the + // notification here. continue; + } futures.add(schedule(hostAdded(upHost))); } else { futures.add(schedule(hostUp(upHost))); } break; case ADDED: - Host newHost = metadata.add(address); - if (newHost != null) { + Host newHost = metadata.newHost(address); + Host previous = metadata.addIfAbsent(newHost); + if (previous == null) { futures.add(schedule(hostAdded(newHost))); - } else { - // If host already existed, retrieve it and check its state, if it's not up schedule a - // hostUp event. - Host existingHost = metadata.getHost(address); - if (!existingHost.isUp()) - futures.add(schedule(hostUp(existingHost))); + } else if (!previous.isUp()) { + futures.add(schedule(hostUp(previous))); } break; case DOWN: diff --git a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java index c1c5531d1ca..b928bcd170b 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java @@ -626,12 +626,12 @@ private static void refreshNodeListAndTokenMap(Connection connection, Cluster.Ma // We don't know that node, create the Host object but wait until we've set the known // info before signaling the addition. Host newHost = cluster.metadata.newHost(foundHosts.get(i)); - Host existing = cluster.metadata.addIfAbsent(newHost); - if (existing == null) { + Host previous = cluster.metadata.addIfAbsent(newHost); + if (previous == null) { host = newHost; isNew = true; } else { - host = existing; + host = previous; isNew = false; } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/Metadata.java b/driver-core/src/main/java/com/datastax/driver/core/Metadata.java index 15e82f2e5b9..1eddbb84ca0 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Metadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Metadata.java @@ -90,13 +90,11 @@ Host newHost(InetSocketAddress address) { return new Host(address, cluster.convictionPolicyFactory, cluster); } + /** + * @return the previous host associated with this socket address, or {@code null} if there was no such host. + */ Host addIfAbsent(Host host) { - Host previous = hosts.putIfAbsent(host.getSocketAddress(), host); - return previous == null ? host : null; - } - - Host add(InetSocketAddress address) { - return addIfAbsent(newHost(address)); + return hosts.putIfAbsent(host.getSocketAddress(), host); } boolean remove(Host host) { From 7c93148ceaf5f5edef77bf4d3449010cd01c05c5 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 15 Sep 2017 15:39:24 -0500 Subject: [PATCH 013/382] JAVA-1619: Update QueryBuilder methods to support Iterable input --- changelog/README.md | 1 + clirr-ignores.xml | 12 +++++ .../driver/core/querybuilder/Clause.java | 49 +++++++++++-------- .../core/querybuilder/QueryBuilder.java | 31 +++--------- .../core/querybuilder/QueryBuilderTest.java | 6 ++- pom.xml | 2 +- upgrade_guide/README.md | 8 +++ 7 files changed, 64 insertions(+), 45 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 6a280752383..60581917209 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -10,6 +10,7 @@ - [improvement] JAVA-1490: Allow zero delay for speculative executions. - [documentation] JAVA-1607: Add FAQ entry for netty-transport-native-epoll. - [bug] JAVA-1630: Fix Metadata.addIfAbsent. +- [improvement] JAVA-1619: Update QueryBuilder methods to support Iterable input. ### 3.3.0 diff --git a/clirr-ignores.xml b/clirr-ignores.xml index 5b59573cc25..e7c34ac458c 100644 --- a/clirr-ignores.xml +++ b/clirr-ignores.xml @@ -147,4 +147,16 @@ False positive, the enclosing class is package-private so this was never exposed + + 7005 + com/datastax/driver/core/querybuilder/QueryBuilder + + * + * + Relaxed parameters from List to Iterable for in, lt, lte, eq, gt, and gte + + diff --git a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Clause.java b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Clause.java index 8b1e83f1f9a..440d65bf6c2 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Clause.java +++ b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/Clause.java @@ -16,7 +16,7 @@ package com.datastax.driver.core.querybuilder; import com.datastax.driver.core.CodecRegistry; - +import com.google.common.collect.Lists; import java.util.List; public abstract class Clause extends Utils.Appendeable { @@ -70,13 +70,14 @@ static class InClause extends AbstractClause { private final List values; - InClause(String name, List values) { + InClause(String name, Iterable values) { super(name); - this.values = values; - if (values == null) throw new IllegalArgumentException("Missing values for IN clause"); - if (values.size() > 65535) + + this.values = Lists.newArrayList(values); + + if (this.values.size() > 65535) throw new IllegalArgumentException("Too many values for IN clause, the maximum allowed is 65535"); } @@ -91,7 +92,7 @@ void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegis // ... IN ? ... // which binds the variable to the full list the IN is on. if (values.size() == 1 && values.get(0) instanceof BindMarker) { - Utils.appendName(name, sb).append(" IN ").append(values.get(0)); + Utils.appendName(name, sb).append(" IN ").append(values.iterator().next()); return; } @@ -178,11 +179,12 @@ static class CompoundClause extends Clause { private final List names; private final List values; - CompoundClause(List names, String op, List values) { - assert names.size() == values.size(); + CompoundClause(Iterable names, String op, Iterable values) { this.op = op; - this.names = names; - this.values = values; + this.names = Lists.newArrayList(names); + this.values = Lists.newArrayList(values); + if (this.names.size() != this.values.size()) + throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", this.names.size(), this.values.size())); } @Override @@ -227,25 +229,32 @@ void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegis static class CompoundInClause extends Clause { private final List names; - private final List valueLists; + private final List valueLists; - public CompoundInClause(List names, List valueLists) { + public CompoundInClause(Iterable names, Iterable valueLists) { if (valueLists == null) throw new IllegalArgumentException("Missing values for IN clause"); - if (valueLists.size() > 65535) - throw new IllegalArgumentException("Too many values for IN clause, the maximum allowed is 65535"); + if (names == null) + throw new IllegalArgumentException("Missing names for IN clause"); + + this.names = Lists.newArrayList(names); + this.valueLists = Lists.newArrayList(); + for (Object value : valueLists) { - if (value instanceof List) { - List tuple = (List) value; - if (tuple.size() != names.size()) { - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), tuple.size())); + if (value instanceof Iterable) { + List tuple = Lists.newArrayList((Iterable) value); + if (tuple.size() != this.names.size()) { + throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", this.names.size(), tuple.size())); } + this.valueLists.add(tuple); } else if (!(value instanceof BindMarker)) { throw new IllegalArgumentException(String.format("Wrong element type for values list, expected List or BindMarker, got %s", value.getClass().getName())); + } else { + this.valueLists.add(value); } } - this.names = names; - this.valueLists = valueLists; + if (this.valueLists.size() > 65535) + throw new IllegalArgumentException("Too many values for IN clause, the maximum allowed is 65535"); } @Override diff --git a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/QueryBuilder.java b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/QueryBuilder.java index 5400266976c..1d03c349aa4 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/querybuilder/QueryBuilder.java +++ b/driver-core/src/main/java/com/datastax/driver/core/querybuilder/QueryBuilder.java @@ -313,10 +313,7 @@ public static Clause eq(String name, Object value) { * @return the corresponding where clause. * @throws IllegalArgumentException if {@code names.size() != values.size()}. */ - public static Clause eq(List names, List values) { - if (names.size() != values.size()) - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), values.size())); - + public static Clause eq(Iterable names, Iterable values) { return new Clause.CompoundClause(names, "=", values); } @@ -351,7 +348,7 @@ public static Clause in(String name, Object... values) { * @param values the values * @return the corresponding where clause. */ - public static Clause in(String name, List values) { + public static Clause in(String name, Iterable values) { return new Clause.InClause(name, values); } @@ -361,7 +358,7 @@ public static Clause in(String name, List values) { * For instance, {@code in(Arrays.asList("a", "b"), Arrays.asList(Arrays.asList(1, "foo"), Arrays.asList(2, "bar")))} * will generate the CQL {@code WHERE} clause {@code (a, b) IN ((1, 'foo'), (2, 'bar'))}. *

- * Each element in {@code values} must be either a {@link List list} containing exactly as many values + * Each element in {@code values} must be either an {@link Iterable iterable} containing exactly as many values * as there are columns to match in {@code names}, * or a {@link #bindMarker() bind marker} – in which case, that marker is to be considered as * a placeholder for one whole tuple of values to match. @@ -374,7 +371,7 @@ public static Clause in(String name, List values) { * @throws IllegalArgumentException if the size of any tuple in {@code values} is not equal to {@code names.size()}, * or if {@code values} contains elements that are neither {@link List lists} nor {@link #bindMarker() bind markers}. */ - public static Clause in(List names, List values) { + public static Clause in(Iterable names, Iterable values) { return new Clause.CompoundInClause(names, values); } @@ -427,10 +424,7 @@ public static Clause lt(String name, Object value) { * @return the corresponding where clause. * @throws IllegalArgumentException if {@code names.size() != values.size()}. */ - public static Clause lt(List names, List values) { - if (names.size() != values.size()) - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), values.size())); - + public static Clause lt(Iterable names, Iterable values) { return new Clause.CompoundClause(names, "<", values); } @@ -459,10 +453,7 @@ public static Clause lte(String name, Object value) { * @return the corresponding where clause. * @throws IllegalArgumentException if {@code names.size() != values.size()}. */ - public static Clause lte(List names, List values) { - if (names.size() != values.size()) - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), values.size())); - + public static Clause lte(Iterable names, Iterable values) { return new Clause.CompoundClause(names, "<=", values); } @@ -491,10 +482,7 @@ public static Clause gt(String name, Object value) { * @return the corresponding where clause. * @throws IllegalArgumentException if {@code names.size() != values.size()}. */ - public static Clause gt(List names, List values) { - if (names.size() != values.size()) - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), values.size())); - + public static Clause gt(Iterable names, Iterable values) { return new Clause.CompoundClause(names, ">", values); } @@ -523,10 +511,7 @@ public static Clause gte(String name, Object value) { * @return the corresponding where clause. * @throws IllegalArgumentException if {@code names.size() != values.size()}. */ - public static Clause gte(List names, List values) { - if (names.size() != values.size()) - throw new IllegalArgumentException(String.format("The number of names (%d) and values (%d) don't match", names.size(), values.size())); - + public static Clause gte(Iterable names, Iterable values) { return new Clause.CompoundClause(names, ">=", values); } diff --git a/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java b/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java index 91cf75b4243..7e1203661c0 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/querybuilder/QueryBuilderTest.java @@ -611,6 +611,10 @@ public void selectInjectionTests() throws Exception { select = select("a", "b").from("foo").where(in("a", "b", "c'); --comment")); assertEquals(select.toString(), query); + query = "SELECT a,b FROM foo WHERE a IN ('a','b','c');"; + select = select("a", "b").from("foo").where(in("a", Sets.newLinkedHashSet(Arrays.asList("a", "b", "c")))); + assertEquals(select.toString(), query); + // User Injection? query = "SELECT * FROM bar; --(b) FROM foo;"; select = select().fcall("* FROM bar; --", column("b")).from("foo"); @@ -817,7 +821,7 @@ public void compoundWhereClauseTest() throws Exception { @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Too many values for IN clause, the maximum allowed is 65535") public void should_fail_if_compound_in_clause_has_too_many_values() { - List values = Collections.nCopies(65536, "a"); + List values = Collections.nCopies(65536, bindMarker()); select().all().from("foo").where(eq("k", 4)).and(in(ImmutableList.of("name"), values)); } diff --git a/pom.xml b/pom.xml index d364e879a98..e31383cc2d6 100644 --- a/pom.xml +++ b/pom.xml @@ -631,7 +631,7 @@ - 3.2.0 + 3.3.0 ../clirr-ignores.xml com/datastax/shaded/** diff --git a/upgrade_guide/README.md b/upgrade_guide/README.md index 3fe68aedc74..b278a1491d5 100644 --- a/upgrade_guide/README.md +++ b/upgrade_guide/README.md @@ -3,6 +3,14 @@ The purpose of this guide is to detail changes made by successive versions of the Java driver. +### 3.4.0 + +`QueryBuilder` methods `in`, `lt`, `lte`, `eq`, `gt`, and `gte` now accept +`Iterable` as input rather than just `List`. This should have no impact unless +you were accessing these methods using reflection in which case you need to +account for these new parameter types. + + ### 3.2.0 The `SSLOptions` interface is now deprecated in favor of From 37d6817cee9736516f56c1d4591e96a517976b2d Mon Sep 17 00:00:00 2001 From: olim7t Date: Wed, 18 Oct 2017 15:50:44 -0700 Subject: [PATCH 014/382] Update docs to 4.0.0-alpha2 --- docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.yaml b/docs.yaml index 8b47643224b..2e77198921c 100644 --- a/docs.yaml +++ b/docs.yaml @@ -54,7 +54,7 @@ versions: - name: '3.3' ref: '3.3.0' - name: '4.0-alpha' - ref: '4.0.0-alpha1' + ref: '4.0.0-alpha2' - name: '3.2' ref: '3.2_docfixes' - name: '3.1' From 89f14bc40d6c6250f90938a129113a52f9d6743c Mon Sep 17 00:00:00 2001 From: Kevin Gallardo Date: Thu, 26 Oct 2017 17:16:52 -0400 Subject: [PATCH 015/382] JAVA-1527: Expose host_id and schema_version in Host metadata. (#890) --- changelog/README.md | 1 + .../driver/core/ControlConnection.java | 12 ++++++ .../java/com/datastax/driver/core/Host.java | 38 +++++++++++++++++++ .../com/datastax/driver/core/HostAssert.java | 11 ++++++ .../core/HostMetadataIntegrationTest.java | 37 ++++++++++++++++++ .../driver/core/ScassandraCluster.java | 2 + 6 files changed, 101 insertions(+) diff --git a/changelog/README.md b/changelog/README.md index 60581917209..9c18f63d5ce 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -11,6 +11,7 @@ - [documentation] JAVA-1607: Add FAQ entry for netty-transport-native-epoll. - [bug] JAVA-1630: Fix Metadata.addIfAbsent. - [improvement] JAVA-1619: Update QueryBuilder methods to support Iterable input. +- [improvement] JAVA-1527: Expose host_id and schema_version on Host metadata. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java index b928bcd170b..1699d8d626b 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java @@ -516,6 +516,8 @@ private static void updateInfo(Host host, Row row, Cluster.Manager cluster, bool String dseVersion = row.getString("dse_version"); host.setDseVersion(dseVersion); } + host.setHostId(row.getUUID("host_id")); + host.setSchemaVersion(row.getUUID("schema_version")); } private static void updateLocationInfo(Host host, String datacenter, String rack, boolean isInitialConnection, Cluster.Manager cluster) { @@ -588,6 +590,8 @@ private static void refreshNodeListAndTokenMap(Connection connection, Cluster.Ma List dseVersions = new ArrayList(); List dseGraphEnabled = new ArrayList(); List dseWorkloads = new ArrayList(); + List hostIds = new ArrayList(); + List schemaVersions = new ArrayList(); for (Row row : peersFuture.get()) { if (!isValidPeer(row, logInvalidPeers)) @@ -617,6 +621,8 @@ private static void refreshNodeListAndTokenMap(Connection connection, Cluster.Ma dseGraphEnabled.add(isDseGraph); String dseVersion = row.getColumnDefinitions().contains("dse_version") ? row.getString("dse_version") : null; dseVersions.add(dseVersion); + hostIds.add(row.getUUID("host_id")); + schemaVersions.add(row.getUUID("schema_version")); } for (int i = 0; i < foundHosts.size(); i++) { @@ -650,6 +656,12 @@ private static void refreshNodeListAndTokenMap(Connection connection, Cluster.Ma host.setDseWorkload(dseWorkloads.get(i)); if (dseGraphEnabled.get(i) != null) host.setDseGraphEnabled(dseGraphEnabled.get(i)); + if (hostIds.get(i) != null) { + host.setHostId(hostIds.get(i)); + } + if (schemaVersions.get(i) != null) { + host.setSchemaVersion(schemaVersions.get(i)); + } if (metadataEnabled && factory != null && allTokens.get(i) != null) tokenMap.put(host, allTokens.get(i)); diff --git a/driver-core/src/main/java/com/datastax/driver/core/Host.java b/driver-core/src/main/java/com/datastax/driver/core/Host.java index 70aa7ac7f5f..4c4009c7739 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Host.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Host.java @@ -24,6 +24,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; @@ -52,6 +53,10 @@ public class Host { // specified otherwise in cassandra.yaml file. private volatile InetAddress listenAddress; + private volatile UUID hostId; + + private volatile UUID schemaVersion; + enum State {ADDED, DOWN, UP} volatile State state; @@ -137,6 +142,14 @@ void setDseGraphEnabled(boolean dseGraphEnabled) { this.dseGraphEnabled = dseGraphEnabled; } + void setHostId(UUID hostId) { + this.hostId = hostId; + } + + void setSchemaVersion(UUID schemaVersion) { + this.schemaVersion = schemaVersion; + } + boolean supports(ProtocolVersion version) { return getCassandraVersion() == null || version.minCassandraVersion().compareTo(getCassandraVersion().nextStable()) <= 0; @@ -303,6 +316,31 @@ public boolean isDseGraphEnabled() { return dseGraphEnabled; } + /** + * Return the host id value for the host. + *

+ * The host id is the main identifier used by Cassandra on the server for internal + * communication (gossip). It is referenced as the column {@code host_id} in the + * {@code system.local} or {@code system.peers} table. + * + * @return the node's host id value. + */ + public UUID getHostId() { + return hostId; + } + + /** + * Return the current schema version for the host. + *

+ * Schema versions in Cassandra are used to ensure all the nodes agree on the current + * Cassandra schema when it is modified. For more information see {@link ExecutionInfo#isSchemaInAgreement()} + * + * @return the node's current schema version value. + */ + public UUID getSchemaVersion() { + return schemaVersion; + } + /** * Returns the tokens that this host owns. * diff --git a/driver-core/src/test/java/com/datastax/driver/core/HostAssert.java b/driver-core/src/test/java/com/datastax/driver/core/HostAssert.java index 4f9573269ab..bdd66e9c43a 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/HostAssert.java +++ b/driver-core/src/test/java/com/datastax/driver/core/HostAssert.java @@ -21,6 +21,7 @@ import org.assertj.core.api.AbstractAssert; import java.net.InetAddress; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -197,4 +198,14 @@ public HostAssert hasNoBroadcastAddress() { assertThat(actual.getBroadcastAddress()).isNull(); return this; } + + public HostAssert hasHostId(UUID hostId) { + assertThat(actual.getHostId()).isEqualTo(hostId); + return this; + } + + public HostAssert hasSchemaVersion(UUID schemaVersion) { + assertThat(actual.getSchemaVersion()).isEqualTo(schemaVersion); + return this; + } } diff --git a/driver-core/src/test/java/com/datastax/driver/core/HostMetadataIntegrationTest.java b/driver-core/src/test/java/com/datastax/driver/core/HostMetadataIntegrationTest.java index 12f7649a991..ca47236823c 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/HostMetadataIntegrationTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/HostMetadataIntegrationTest.java @@ -15,11 +15,13 @@ */ package com.datastax.driver.core; +import com.datastax.driver.core.utils.UUIDs; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.testng.annotations.Test; import java.net.InetAddress; +import java.util.UUID; import static com.datastax.driver.core.Assertions.assertThat; import static com.datastax.driver.core.TestUtils.nonQuietClusterCloseOptions; @@ -317,4 +319,39 @@ public void should_set_listen_address_if_available() { scassandraCluster.stop(); } } + + @Test(groups = "short") + public void should_parse_host_id_and_schema_version() { + UUID hostId1 = UUIDs.random(); + UUID hostId2 = UUIDs.random(); + UUID schemaVersion = UUIDs.random(); + + ScassandraCluster scassandraCluster = ScassandraCluster.builder() + .withIpPrefix(TestUtils.IP_PREFIX) + .withNodes(2) + .forcePeerInfo(1, 1, "host_id", hostId1) + .forcePeerInfo(1, 1, "schema_version", schemaVersion) + .forcePeerInfo(1, 2, "host_id", hostId2) + .forcePeerInfo(1, 2, "schema_version", schemaVersion) + .build(); + + Cluster cluster = Cluster.builder() + .addContactPoints(scassandraCluster.address(1).getAddress()) + .withPort(scassandraCluster.getBinaryPort()) + .build(); + + try { + scassandraCluster.init(); + cluster.init(); + + assertThat(cluster).host(1).hasHostId(hostId1); + assertThat(cluster).host(1).hasSchemaVersion(schemaVersion); + assertThat(cluster).host(2).hasHostId(hostId2); + assertThat(cluster).host(2).hasSchemaVersion(schemaVersion); + + } finally { + cluster.close(); + scassandraCluster.stop(); + } + } } diff --git a/driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java b/driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java index 348eb8e7579..87169aef2d3 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java +++ b/driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java @@ -334,6 +334,7 @@ private void primeMetadata(Scassandra node) { addPeerInfo(row, dc, n + 1, "rack", getPeerInfo(dc, n + 1, "rack", "rack1")); addPeerInfo(row, dc, n + 1, "release_version", getPeerInfo(dc, n + 1, "release_version", cassandraVersion)); addPeerInfo(row, dc, n + 1, "tokens", ImmutableSet.of(tokens.get(n))); + addPeerInfo(row, dc, n + 1, "host_id", UUIDs.random()); addPeerInfo(row, dc, n + 1, "schema_version", schemaVersion); addPeerInfo(row, dc, n + 1, "graph", false); @@ -461,6 +462,7 @@ private Object getPeerInfo(int dc, int node, String property, Object defaultValu column("release_version", TEXT), column("tokens", set(TEXT)), column("graph", BOOLEAN), + column("host_id", UUID), column("schema_version", UUID) }; From 3f654e27d2bb3ade5f0c1966cbbccb092399c868 Mon Sep 17 00:00:00 2001 From: Michael Figuiere Date: Thu, 28 Sep 2017 10:11:34 -0700 Subject: [PATCH 016/382] JAVA-1632: Add a withIpPrefix(String) method to CCMBridge.Builder --- .../com/datastax/driver/core/CCMBridge.java | 64 ++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java index e103f0d4c7e..d79a8e8ae34 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java @@ -34,7 +34,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.datastax.driver.core.TestUtils.*; +import static com.datastax.driver.core.TestUtils.executeNoFail; public class CCMBridge implements CCMAccess { @@ -270,6 +270,8 @@ public static boolean isWindows() { private final int binaryPort; + private final String ipPrefix; + private final File ccmDir; private final boolean isDSE; @@ -284,11 +286,12 @@ public static boolean isWindows() { private final int[] nodes; - private CCMBridge(String clusterName, VersionNumber cassandraVersion, VersionNumber dseVersion, + private CCMBridge(String clusterName, VersionNumber cassandraVersion, VersionNumber dseVersion, String ipPrefix, int storagePort, int thriftPort, int binaryPort, String jvmArgs, int[] nodes) { this.clusterName = clusterName; this.cassandraVersion = cassandraVersion; this.dseVersion = dseVersion; + this.ipPrefix = ipPrefix; this.storagePort = storagePort; this.thriftPort = thriftPort; this.binaryPort = binaryPort; @@ -307,9 +310,13 @@ public String getClusterName() { return clusterName; } + protected String ipOfNode(int n) { + return ipPrefix + n; + } + @Override public InetSocketAddress addressOfNode(int n) { - return new InetSocketAddress(TestUtils.ipOfNode(n), binaryPort); + return new InetSocketAddress(ipOfNode(n), binaryPort); } @Override @@ -426,7 +433,7 @@ public synchronized void start() { for (int dc = 1; dc <= nodes.length; dc++) { int nodesInDc = nodes[dc - 1]; for (int i = 0; i < nodesInDc; i++) { - InetSocketAddress addr = new InetSocketAddress(ipOfNode(n), binaryPort); + InetSocketAddress addr = addressOfNode(n); logger.debug("Waiting for binary protocol to show up for {}", addr); TestUtils.waitUntilPortIsUp(addr); n++; @@ -487,7 +494,7 @@ public String checkForErrors() { @Override public void start(int n) { - logger.debug(String.format("Starting: node %s (%s%s:%s) in %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Starting: node %s (%s%s:%s) in %s", n, ipPrefix, n, binaryPort, this)); try { String cmd = CCM_COMMAND + " node%d start " + jvmArgs + getStartWaitArguments(); if (isWindows() && this.cassandraVersion.compareTo(VersionNumber.parse("2.2.4")) >= 0) { @@ -511,31 +518,31 @@ public void start(int n) { @Override public void stop(int n) { - logger.debug(String.format("Stopping: node %s (%s%s:%s) in %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Stopping: node %s (%s%s:%s) in %s", n, ipPrefix, n, binaryPort, this)); execute(CCM_COMMAND + " node%d stop", n); } @Override public void forceStop(int n) { - logger.debug(String.format("Force stopping: node %s (%s%s:%s) in %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Force stopping: node %s (%s%s:%s) in %s", n, ipPrefix, n, binaryPort, this)); execute(CCM_COMMAND + " node%d stop --not-gently", n); } @Override public void pause(int n) { - logger.debug(String.format("Pausing: node %s (%s%s:%s) in %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Pausing: node %s (%s%s:%s) in %s", n, ipPrefix, n, binaryPort, this)); execute(CCM_COMMAND + " node%d pause", n); } @Override public void resume(int n) { - logger.debug(String.format("Resuming: node %s (%s%s:%s) in %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Resuming: node %s (%s%s:%s) in %s", n, ipPrefix, n, binaryPort, this)); execute(CCM_COMMAND + " node%d resume", n); } @Override public void remove(int n) { - logger.debug(String.format("Removing: node %s (%s%s:%s) from %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Removing: node %s (%s%s:%s) from %s", n, ipPrefix, n, binaryPort, this)); execute(CCM_COMMAND + " node%d remove", n); } @@ -546,18 +553,18 @@ public void add(int n) { @Override public void add(int dc, int n) { - logger.debug(String.format("Adding: node %s (%s%s:%s) to %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); - String thriftItf = TestUtils.ipOfNode(n) + ":" + thriftPort; - String storageItf = TestUtils.ipOfNode(n) + ":" + storagePort; - String binaryItf = TestUtils.ipOfNode(n) + ":" + binaryPort; - String remoteLogItf = TestUtils.ipOfNode(n) + ":" + TestUtils.findAvailablePort(); + logger.debug(String.format("Adding: node %s (%s%s:%s) to %s", n, ipPrefix, n, binaryPort, this)); + String thriftItf = ipOfNode(n) + ":" + thriftPort; + String storageItf = ipOfNode(n) + ":" + storagePort; + String binaryItf = ipOfNode(n) + ":" + binaryPort; + String remoteLogItf = ipOfNode(n) + ":" + TestUtils.findAvailablePort(); execute(CCM_COMMAND + " add node%d -d dc%s -i %s%d -t %s -l %s --binary-itf %s -j %d -r %s -s -b" + (isDSE ? " --dse" : ""), - n, dc, TestUtils.IP_PREFIX, n, thriftItf, storageItf, binaryItf, TestUtils.findAvailablePort(), remoteLogItf); + n, dc, ipPrefix, n, thriftItf, storageItf, binaryItf, TestUtils.findAvailablePort(), remoteLogItf); } @Override public void decommission(int n) { - logger.debug(String.format("Decommissioning: node %s (%s%s:%s) from %s", n, TestUtils.IP_PREFIX, n, binaryPort, this)); + logger.debug(String.format("Decommissioning: node %s (%s%s:%s) from %s", n, ipPrefix, n, binaryPort, this)); // Special case for C* 3.12+, DSE 5.1+, force decommission (see CASSANDRA-12510) String cmd = CCM_COMMAND + " node%d decommission"; if (this.cassandraVersion.compareTo(VersionNumber.parse("3.12")) >= 0) { @@ -780,6 +787,7 @@ public static class Builder { public static final String RANDOM_PORT = "__RANDOM_PORT__"; private static final Pattern RANDOM_PORT_PATTERN = Pattern.compile(RANDOM_PORT); + private String ipPrefix = TestUtils.IP_PREFIX; int[] nodes = {1}; private boolean start = true; private boolean dse = false; @@ -797,6 +805,14 @@ private Builder() { cassandraConfiguration.put("native_transport_port", RANDOM_PORT); } + /** + * IP Prefix to use for the address of each node. Its format has to be like {@code "127.1.1."}. + */ + public Builder withIpPrefix(String ipPrefix) { + this.ipPrefix = ipPrefix; + return this; + } + /** * Number of hosts for each DC. Defaults to [1] (1 DC with 1 node) */ @@ -949,7 +965,7 @@ public CCMBridge build() { cassandraConfiguration.remove("rpc_port"); cassandraConfiguration.remove("thrift_prepared_statements_cache_size_mb"); } - final CCMBridge ccm = new CCMBridge(clusterName, cassandraVersion, dseVersion, storagePort, thriftPort, binaryPort, joinJvmArgs(), nodes); + final CCMBridge ccm = new CCMBridge(clusterName, cassandraVersion, dseVersion, ipPrefix, storagePort, thriftPort, binaryPort, joinJvmArgs(), nodes); Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -1010,7 +1026,7 @@ private String buildCreateCommand(String clusterName, boolean versionConfigured, cassandraVersion, VersionNumber dseVersion) { StringBuilder result = new StringBuilder(CCM_COMMAND + " create"); result.append(" ").append(clusterName); - result.append(" -i ").append(TestUtils.IP_PREFIX); + result.append(" -i ").append(ipPrefix); result.append(" "); if (nodes.length > 0) { result.append(" -n "); @@ -1052,8 +1068,8 @@ private void updateNodeConf(CCMBridge ccm) { for (int dc = 1; dc <= nodes.length; dc++) { int nodesInDc = nodes[dc - 1]; for (int i = 0; i < nodesInDc; i++) { - int jmxPort = findAvailablePort(); - int debugPort = findAvailablePort(); + int jmxPort = TestUtils.findAvailablePort(); + int debugPort = TestUtils.findAvailablePort(); logger.trace("Node {} in cluster {} using JMX port {} and debug port {}", n, ccm.getClusterName(), jmxPort, debugPort); File nodeConf = new File(ccm.getNodeDir(n), "node.conf"); File nodeConf2 = new File(ccm.getNodeDir(n), "node.conf.tmp"); @@ -1068,7 +1084,7 @@ private void updateNodeConf(CCMBridge ccm) { if (line.startsWith("jmx_port")) { line = String.format("jmx_port: '%s'", jmxPort); } else if (line.startsWith("remote_debug_port")) { - line = String.format("remote_debug_port: %s:%s", TestUtils.ipOfNode(n), debugPort); + line = String.format("remote_debug_port: %s:%s", ipPrefix + n, debugPort); } pw.println(line); } @@ -1128,6 +1144,7 @@ public boolean equals(Object o) { Builder builder = (Builder) o; + if (ipPrefix != builder.ipPrefix) return false; if (dse != builder.dse) return false; if (!Arrays.equals(nodes, builder.nodes)) return false; if (version != null ? !version.equals(builder.version) : builder.version != null) return false; @@ -1143,6 +1160,7 @@ public int hashCode() { // do not include start as it is not relevant to the settings of the cluster. int result = Arrays.hashCode(nodes); result = 31 * result + (dse ? 1 : 0); + result = 31 * result + ipPrefix.hashCode(); result = 31 * result + (version != null ? version.hashCode() : 0); result = 31 * result + createOptions.hashCode(); result = 31 * result + jvmArgs.hashCode(); @@ -1153,4 +1171,4 @@ public int hashCode() { } } -} +} \ No newline at end of file From 841089a33845a4d5ceed6e5870239ee28bd97cc1 Mon Sep 17 00:00:00 2001 From: Michael Figuiere Date: Tue, 26 Sep 2017 22:45:38 -0700 Subject: [PATCH 017/382] JAVA-1631 Publish a sources jar for driver-core-tests --- driver-core/pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 0cb71e8ef08..2fcf924672a 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -189,6 +189,18 @@ We avoid packaging bundle because it does not play nicely with the shade plugin, see https://stackoverflow.com/questions/31262032/maven-shade-plugin-and-custom-packaging-type --> + + org.apache.maven.plugins + maven-source-plugin + + + attach-test-sources + + test-jar-no-fork + + + + org.apache.felix maven-bundle-plugin From a5914648eafad8b905207fb7268d22b9d623faa3 Mon Sep 17 00:00:00 2001 From: tommystendahl Date: Fri, 27 Oct 2017 00:24:23 +0200 Subject: [PATCH 018/382] JAVA-1377: Add support for TWCS in SchemaBuilder (#897) --- changelog/README.md | 2 + .../core/schemabuilder/SchemaBuilder.java | 11 + .../core/schemabuilder/TableOptions.java | 204 +++++++++++++++++- .../schemabuilder/CompactionOptionsTest.java | 42 +++- 4 files changed, 253 insertions(+), 6 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 9c18f63d5ce..bc3a45e1f04 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -2,6 +2,7 @@ ### 3.4.0 (In progress) +- [improvement] JAVA-1377: Add support for TWCS in SchemaBuilder. - [bug] JAVA-1555: Include VIEW and CDC in WriteType. - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery @@ -12,6 +13,7 @@ - [bug] JAVA-1630: Fix Metadata.addIfAbsent. - [improvement] JAVA-1619: Update QueryBuilder methods to support Iterable input. - [improvement] JAVA-1527: Expose host_id and schema_version on Host metadata. +- [new feature] JAVA-1377: Add support for TWCS in SchemaBuilder. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/SchemaBuilder.java b/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/SchemaBuilder.java index bad84a7acca..3162e2f5dcf 100755 --- a/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/SchemaBuilder.java +++ b/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/SchemaBuilder.java @@ -256,6 +256,17 @@ public static TableOptions.CompactionOptions.DateTieredCompactionStrategyOptions return new TableOptions.CompactionOptions.DateTieredCompactionStrategyOptions(); } + /** + * Create options for the time window compaction strategy, to use in a CREATE or ALTER TABLE statement. + *

+ * This strategy was introduced in Cassandra 3.0.8 and 3.9. + * + * @return the options. + */ + public static TableOptions.CompactionOptions.TimeWindowCompactionStrategyOptions timeWindowCompactionStrategy() { + return new TableOptions.CompactionOptions.TimeWindowCompactionStrategyOptions(); + } + /** * Create options for the {@code NONE} compression strategy, to use in a CREATE or ALTER TABLE statement. * diff --git a/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/TableOptions.java b/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/TableOptions.java index a05029e223f..9771d3c88c0 100755 --- a/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/TableOptions.java +++ b/driver-core/src/main/java/com/datastax/driver/core/schemabuilder/TableOptions.java @@ -506,8 +506,9 @@ static void validateRateValue(Double rateValue, String property) { *

* To create instances, use * {@link SchemaBuilder#sizedTieredStategy()}, - * {@link SchemaBuilder#leveledStrategy()} or - * {@link SchemaBuilder#dateTieredStrategy()} + * {@link SchemaBuilder#leveledStrategy()}, + * {@link SchemaBuilder#dateTieredStrategy()} or + * {@link SchemaBuilder#timeWindowCompactionStrategy()} */ public static abstract class CompactionOptions { @@ -940,10 +941,205 @@ public String build() { } /** - * Compaction strategies. Possible values: SIZED_TIERED, LEVELED & DATE_TIERED + * Compaction options specific to the time window strategy. + */ + public static class TimeWindowCompactionStrategyOptions extends CompactionOptions { + + public enum CompactionWindowUnit {MINUTES, HOURS, DAYS} + + public enum TimeStampResolution {MICROSECONDS, MILLISECONDS} + + private Optional bucketHigh = Optional.absent(); + + private Optional bucketLow = Optional.absent(); + + private Optional compactionWindowUnit = Optional.absent(); + + private Optional compactionWindowSize = Optional.absent(); + + private Optional minThreshold = Optional.absent(); + + private Optional maxThreshold = Optional.absent(); + + private Optional minSSTableSizeInBytes = Optional.absent(); + + private Optional timestampResolution = Optional.absent(); + + private Optional unsafeAggressiveSSTableExpiration = Optional.absent(); + + TimeWindowCompactionStrategyOptions() { + super(Strategy.TIME_WINDOW); + } + + /** + * Size-tiered compaction strategy (STCS) is used in the newest window, this method sets the bucketHigh value used in STCS. + *

+ * If no call is made to this method, the default value set by Cassandra is 1.5. + * + * @param bucketHigh the new value. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions bucketHigh(Double bucketHigh) { + this.bucketHigh = Optional.fromNullable(bucketHigh); + return this; + } + + /** + * Size-tiered compaction strategy (STCS) is used in the newest window, this method sets the bucketLow value used in STCS. + *

+ * If no call is made to this method, the default value set by Cassandra is 0.5. + * + * @param bucketLow the new value. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions bucketLow(Double bucketLow) { + this.bucketLow = Optional.fromNullable(bucketLow); + return this; + } + + /** + * Sets the time unit used to define the window size + *

+ * If no call is made to this method, the default value set by Cassandra is {@code DAYS}. + * + * @param compactionWindowUnit {@link CompactionWindowUnit#MINUTES}, {@link CompactionWindowUnit#HOURS} or {@link CompactionWindowUnit#DAYS}. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions compactionWindowUnit(CompactionWindowUnit compactionWindowUnit) { + this.compactionWindowUnit = Optional.fromNullable(compactionWindowUnit); + return this; + } + + /** + * Sets the number of units that make up a window. + *

+ * If no call is made to this method, the default value set by Cassandra is 1. + * + * @param compactionWindowSize the size of the first window. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions compactionWindowSize(Integer compactionWindowSize) { + this.compactionWindowSize = Optional.fromNullable(compactionWindowSize); + return this; + } + + /** + * Sets the minimum number of SSTables to trigger a minor compaction + *

+ * If no call is made to this method, the default value set by Cassandra is 4. + * + * @param minThreshold the new value. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions minThreshold(Integer minThreshold) { + this.minThreshold = Optional.fromNullable(minThreshold); + return this; + } + + /** + * Sets the maximum number of SSTables to allow in a minor compaction. + *

+ * If no call is made to this method, the default value set by Cassandra is 32. + * + * @param maxThreshold the new value. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions maxThreshold(Integer maxThreshold) { + this.maxThreshold = Optional.fromNullable(maxThreshold); + return this; + } + + /** + * Size-tiered compaction strategy (STCS) is used in the newest window, this method sets the minSSTableSize value used in STCS. + *

+ * If no call is made to this method, the default value set by Cassandra is 52428800 (50 MB). + * + * @param minSSTableSize the new value. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions minSSTableSizeInBytes(Long minSSTableSize) { + this.minSSTableSizeInBytes = Optional.fromNullable(minSSTableSize); + return this; + } + + /** + * Sets the timestamp resolution, depending on the timestamp unit of the data you insert. + *

+ * If no call is made to this method, the default value set by Cassandra is {@code MICROSECONDS}. + * + * @param timestampResolution {@link TimeStampResolution#MICROSECONDS} or {@link TimeStampResolution#MILLISECONDS}. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions timestampResolution(TimeStampResolution timestampResolution) { + this.timestampResolution = Optional.fromNullable(timestampResolution); + return this; + } + + /** + * Allow expired sstables to be dropped without checking if its data is shadowing other sstables. + * This is a potentially risky option that can lead to data loss or deleted data re-appearing. + *

+ * If no call is made to this method, the default value set by Cassandra is false. + * + * @param unsafeAggressiveSSTableExpiration whether to enable unsafe aggressive sstable expiration option. + * @return this object (for call chaining). + */ + public TimeWindowCompactionStrategyOptions unsafeAggressiveSSTableExpiration(Boolean unsafeAggressiveSSTableExpiration) { + this.unsafeAggressiveSSTableExpiration = Optional.fromNullable(unsafeAggressiveSSTableExpiration); + return this; + } + + @Override + public String build() { + final List generalOptions = super.buildCommonOptions(); + + List options = new ArrayList(generalOptions); + + if (bucketHigh.isPresent()) { + options.add("'bucket_high' : " + bucketHigh.get()); + } + + if (bucketLow.isPresent()) { + options.add("'bucket_low' : " + bucketLow.get()); + } + + if (compactionWindowUnit.isPresent()) { + options.add("'compaction_window_unit' : '" + compactionWindowUnit.get() + "'"); + } + + if (compactionWindowSize.isPresent()) { + options.add("'compaction_window_size' : " + compactionWindowSize.get()); + } + + if (minThreshold.isPresent()) { + options.add("'min_threshold' : " + minThreshold.get()); + } + + if (maxThreshold.isPresent()) { + options.add("'max_threshold' : " + maxThreshold.get()); + } + + if (minSSTableSizeInBytes.isPresent()) { + options.add("'min_sstable_size' : " + minSSTableSizeInBytes.get()); + } + + if (timestampResolution.isPresent()) { + options.add("'timestamp_resolution' : '" + timestampResolution.get() + "'"); + } + + if (unsafeAggressiveSSTableExpiration.isPresent()) { + options.add("'unsafe_aggressive_sstable_expiration' : '" + unsafeAggressiveSSTableExpiration.get() + "'"); + } + + return "{" + Joiner.on(", ").join(options) + "}"; + } + } + + /** + * Compaction strategies. Possible values: SIZED_TIERED, LEVELED, DATE_TIERED AND TIME_WINDOW */ public static enum Strategy { - SIZED_TIERED("'SizeTieredCompactionStrategy'"), LEVELED("'LeveledCompactionStrategy'"), DATE_TIERED("'DateTieredCompactionStrategy'"); + SIZED_TIERED("'SizeTieredCompactionStrategy'"), LEVELED("'LeveledCompactionStrategy'"), DATE_TIERED("'DateTieredCompactionStrategy'"), TIME_WINDOW("'TimeWindowCompactionStrategy'"); private String strategyClass; diff --git a/driver-core/src/test/java/com/datastax/driver/core/schemabuilder/CompactionOptionsTest.java b/driver-core/src/test/java/com/datastax/driver/core/schemabuilder/CompactionOptionsTest.java index b5f01a92d05..dfff5765a38 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/schemabuilder/CompactionOptionsTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/schemabuilder/CompactionOptionsTest.java @@ -18,7 +18,9 @@ import org.testng.annotations.Test; import static com.datastax.driver.core.schemabuilder.SchemaBuilder.*; -import static com.datastax.driver.core.schemabuilder.TableOptions.CompactionOptions.DateTieredCompactionStrategyOptions.TimeStampResolution; +import static com.datastax.driver.core.schemabuilder.TableOptions.CompactionOptions.DateTieredCompactionStrategyOptions; +import static com.datastax.driver.core.schemabuilder.TableOptions.CompactionOptions.TimeWindowCompactionStrategyOptions; +import static com.datastax.driver.core.schemabuilder.TableOptions.CompactionOptions.TimeWindowCompactionStrategyOptions.CompactionWindowUnit; import static org.assertj.core.api.Assertions.assertThat; public class CompactionOptionsTest { @@ -82,7 +84,7 @@ public void should_create_date_tiered_compaction_option() throws Exception { .maxSSTableAgeDays(400) .minThreshold(2) .maxThreshold(4) - .timestampResolution(TimeStampResolution.MICROSECONDS) + .timestampResolution(DateTieredCompactionStrategyOptions.TimeStampResolution.MICROSECONDS) .tombstoneCompactionIntervalInDay(3) .tombstoneThreshold(0.7) .uncheckedTombstoneCompaction(true) @@ -101,6 +103,42 @@ public void should_create_date_tiered_compaction_option() throws Exception { "'timestamp_resolution' : 'MICROSECONDS'}"); } + @Test(groups = "unit") + public void should_create_time_window_compaction_option() throws Exception { + //When + String built = timeWindowCompactionStrategy() + .bucketLow(0.5) + .bucketHigh(1.2) + .compactionWindowUnit(CompactionWindowUnit.HOURS) + .compactionWindowSize(5) + .enabled(true) + .minThreshold(2) + .maxThreshold(4) + .minSSTableSizeInBytes(5000000L) + .timestampResolution(TimeWindowCompactionStrategyOptions.TimeStampResolution.MICROSECONDS) + .tombstoneCompactionIntervalInDay(3) + .tombstoneThreshold(0.7) + .uncheckedTombstoneCompaction(true) + .unsafeAggressiveSSTableExpiration(true) + .build(); + + //Then + assertThat(built).isEqualTo("{'class' : 'TimeWindowCompactionStrategy', " + + "'enabled' : true, " + + "'tombstone_compaction_interval' : 3, " + + "'tombstone_threshold' : 0.7, " + + "'unchecked_tombstone_compaction' : true, " + + "'bucket_high' : 1.2, " + + "'bucket_low' : 0.5, " + + "'compaction_window_unit' : 'HOURS', " + + "'compaction_window_size' : 5, " + + "'min_threshold' : 2, " + + "'max_threshold' : 4, " + + "'min_sstable_size' : 5000000, " + + "'timestamp_resolution' : 'MICROSECONDS', " + + "'unsafe_aggressive_sstable_expiration' : 'true'}"); + } + @Test(groups = "unit") public void should_handle_freeform_options() { //When From dacffc7fd4791d95cdbf9c35e90f6f15b2834f4a Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Thu, 26 Oct 2017 17:26:16 -0500 Subject: [PATCH 019/382] Update changelog for JAVA-1631 and JAVA-1632 --- changelog/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog/README.md b/changelog/README.md index bc3a45e1f04..39ce1519be3 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -14,6 +14,8 @@ - [improvement] JAVA-1619: Update QueryBuilder methods to support Iterable input. - [improvement] JAVA-1527: Expose host_id and schema_version on Host metadata. - [new feature] JAVA-1377: Add support for TWCS in SchemaBuilder. +- [improvement] JAVA-1631: Publish a sources jar for driver-core-tests. +- [improvement] JAVA-1632: Add a withIpPrefix(String) method to CCMBridge.Builder. ### 3.3.0 From 021bf5d5e48c62165e146c2a955e70376a665b41 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Thu, 26 Oct 2017 17:37:16 -0500 Subject: [PATCH 020/382] Remove duplicate changelog entry --- changelog/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changelog/README.md b/changelog/README.md index 39ce1519be3..0b61e62a432 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -2,7 +2,6 @@ ### 3.4.0 (In progress) -- [improvement] JAVA-1377: Add support for TWCS in SchemaBuilder. - [bug] JAVA-1555: Include VIEW and CDC in WriteType. - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) - [improvement] JAVA-1587: Deterministic ordering of columns used in Mapper#saveQuery From 69cf23bc5aa2fd1765d609ecbe1180cfc5212596 Mon Sep 17 00:00:00 2001 From: emolsson Date: Fri, 27 Oct 2017 17:50:26 +0200 Subject: [PATCH 021/382] JAVA-1639: VersionNumber does not fullfill equals/hashcode contract (#898) --- changelog/README.md | 1 + .../java/com/datastax/driver/core/VersionNumber.java | 2 +- .../java/com/datastax/driver/core/VersionNumberTest.java | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/changelog/README.md b/changelog/README.md index 0b61e62a432..70ab47433cf 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -15,6 +15,7 @@ - [new feature] JAVA-1377: Add support for TWCS in SchemaBuilder. - [improvement] JAVA-1631: Publish a sources jar for driver-core-tests. - [improvement] JAVA-1632: Add a withIpPrefix(String) method to CCMBridge.Builder. +- [bug] JAVA-1639: VersionNumber does not fullfill equals/hashcode contract. ### 3.3.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/VersionNumber.java b/driver-core/src/main/java/com/datastax/driver/core/VersionNumber.java index 2f83dd18606..ff3e4aac83b 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/VersionNumber.java +++ b/driver-core/src/main/java/com/datastax/driver/core/VersionNumber.java @@ -233,7 +233,7 @@ public boolean equals(Object other) { @Override public int hashCode() { - return MoreObjects.hashCode(major, minor, patch, dsePatch, preReleases, build); + return MoreObjects.hashCode(major, minor, patch, dsePatch, Arrays.hashCode(preReleases), build); } @Override diff --git a/driver-core/src/test/java/com/datastax/driver/core/VersionNumberTest.java b/driver-core/src/test/java/com/datastax/driver/core/VersionNumberTest.java index df1601b48b6..c6127a7b5f6 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/VersionNumberTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/VersionNumberTest.java @@ -98,6 +98,15 @@ public void should_order_versions() { assertOrder("2.0.0+build01", "2.0.0+build02", 0); } + @Test(groups = "unit") + public void should_treat_same_prerelease_equal() { + VersionNumber version1 = VersionNumber.parse("3.0.15-SNAPSHOT"); + VersionNumber version2 = VersionNumber.parse("3.0.15-SNAPSHOT"); + + assertThat(version1).isEqualTo(version2); + assertThat(version1.hashCode()).isEqualTo(version2.hashCode()); + } + private void assertOrder(String version1, String version2, int expected) { assertThat(VersionNumber.parse(version1).compareTo(VersionNumber.parse(version2))).isEqualTo(expected); } From 119e051f4c0f438653254153cfc1327afbbdb4fe Mon Sep 17 00:00:00 2001 From: olim7t Date: Thu, 19 Oct 2017 11:23:59 -0700 Subject: [PATCH 022/382] Update reference for 4.x docs (fixed broken links) --- docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.yaml b/docs.yaml index 2e77198921c..b38b86397d7 100644 --- a/docs.yaml +++ b/docs.yaml @@ -54,7 +54,7 @@ versions: - name: '3.3' ref: '3.3.0' - name: '4.0-alpha' - ref: '4.0.0-alpha2' + ref: '9f0edeb' - name: '3.2' ref: '3.2_docfixes' - name: '3.1' From 34093ebcd93e793447a0ad819009ccffc832fc1a Mon Sep 17 00:00:00 2001 From: olim7t Date: Wed, 1 Nov 2017 09:49:45 -0700 Subject: [PATCH 023/382] JAVA-1648: Fix Guava links in docs Refer to the driver's default version. --- manual/custom_codecs/README.md | 2 +- manual/custom_codecs/extras/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manual/custom_codecs/README.md b/manual/custom_codecs/README.md index e30d9534ccf..ead31b9a578 100644 --- a/manual/custom_codecs/README.md +++ b/manual/custom_codecs/README.md @@ -463,7 +463,7 @@ consider using prepared statements all the time. [TupleType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html [TupleValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleValue.html [CustomType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/DataType.CustomType.html -[TypeToken]: http://google.github.io/guava/releases/21.0/api/docs/com/google/common/reflect/TypeToken.html +[TypeToken]: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/reflect/TypeToken.html [SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SimpleStatement.html [BuiltStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/BuiltStatement.html [setList]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SettableByIndexData.html#setList-int-java.util.List- diff --git a/manual/custom_codecs/extras/README.md b/manual/custom_codecs/extras/README.md index 0441cd82d60..94454f28b78 100644 --- a/manual/custom_codecs/extras/README.md +++ b/manual/custom_codecs/extras/README.md @@ -311,7 +311,7 @@ often. [OptionalCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/OptionalCodec.html [Optional]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html -[TypeToken]: http://google.github.io/guava/releases/21.0/api/docs/com/google/common/reflect/TypeToken.html +[TypeToken]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/reflect/TypeToken.html #### Guava @@ -354,7 +354,7 @@ session.execute(pst.bind() See the JDK8 Optional section above for explanations about [TypeToken]. [OptionalCodec_guava]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/guava/OptionalCodec.html -[Optional_guava]: http://google.github.io/guava/releases/21.0/api/docs/com/google/common/base/Optional.html +[Optional_guava]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Optional.html ### Arrays From 514b8ec2c6acd4b9e5a2bb40f770a95a8720bb4a Mon Sep 17 00:00:00 2001 From: olim7t Date: Wed, 1 Nov 2017 09:51:59 -0700 Subject: [PATCH 024/382] Bump version to 3.3.1-SNAPSHOT --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 2fcf924672a..dc75330bc85 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index 765631a4adf..5e78fdeac94 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 185b84ac29c..6493c014516 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index cfcc92c8285..afcc6d863d3 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 9311f2e63cf..eba4e610cf4 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index cda762fdd8b..2616fb75db0 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 1a79b393cc3..dcce75bcfb0 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 98b0f0d47f0..745cc6aa10e 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index e3e9be9aa8b..61f86f6c5dd 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index 1985767b273..aa87180b1f8 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 94fcdf763e2..c518ca88c7d 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index e31383cc2d6..7939b9d11fc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.3.1-SNAPSHOT pom DataStax Java Driver for Apache Cassandra From a593410672bf2f0ef05f1ccffa78075bc76537f6 Mon Sep 17 00:00:00 2001 From: olim7t Date: Wed, 1 Nov 2017 12:00:56 -0700 Subject: [PATCH 025/382] Fix changelog - change latest version - move 1613 to the correct section --- changelog/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 70ab47433cf..3dade10f0e8 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,6 +1,6 @@ ## Changelog -### 3.4.0 (In progress) +### 3.3.1 (In progress) - [bug] JAVA-1555: Include VIEW and CDC in WriteType. - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) @@ -16,6 +16,7 @@ - [improvement] JAVA-1631: Publish a sources jar for driver-core-tests. - [improvement] JAVA-1632: Add a withIpPrefix(String) method to CCMBridge.Builder. - [bug] JAVA-1639: VersionNumber does not fullfill equals/hashcode contract. +- [bug] JAVA-1613: Fix broken shaded Netty detection in NettyUtil. ### 3.3.0 @@ -36,7 +37,6 @@ - [improvement] JAVA-1488: Upgrade Netty to 4.0.47.Final. - [improvement] JAVA-1460: Add speculative execution number to ExecutionInfo - [improvement] JAVA-1431: Improve error handling during pool initialization. -- [bug] JAVA-1613: Fix broken shaded Netty detection in NettyUtil. ### 3.2.0 From cbc1f149afe93bf25dba9aab7ffffebd066421e1 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 7 Nov 2017 13:19:02 -0800 Subject: [PATCH 026/382] Update version in docs --- README.md | 14 ++--- changelog/README.md | 2 +- faq/README.md | 4 +- faq/osgi/README.md | 2 +- manual/README.md | 30 +++++------ manual/address_resolution/README.md | 4 +- manual/async/README.md | 8 +-- manual/auth/README.md | 2 +- manual/compression/README.md | 2 +- manual/custom_codecs/README.md | 38 +++++++------- manual/custom_codecs/extras/README.md | 44 ++++++++-------- manual/custom_payloads/README.md | 4 +- manual/idempotence/README.md | 6 +-- manual/load_balancing/README.md | 34 ++++++------ manual/logging/README.md | 2 +- manual/metadata/README.md | 38 +++++++------- manual/metrics/README.md | 2 +- manual/native_protocol/README.md | 10 ++-- manual/object_mapper/README.md | 2 +- manual/object_mapper/creating/README.md | 24 ++++----- manual/object_mapper/custom_codecs/README.md | 6 +-- manual/object_mapper/using/README.md | 18 +++---- manual/paging/README.md | 4 +- manual/pooling/README.md | 26 +++++----- manual/query_timestamps/README.md | 8 +-- manual/reconnection/README.md | 2 +- manual/retries/README.md | 54 ++++++++++---------- manual/shaded_jar/README.md | 8 +-- manual/socket_options/README.md | 24 ++++----- manual/speculative_execution/README.md | 22 ++++---- manual/ssl/README.md | 10 ++-- manual/statements/README.md | 16 +++--- manual/statements/batch/README.md | 2 +- manual/statements/built/README.md | 2 +- manual/statements/prepared/README.md | 12 ++--- manual/statements/simple/README.md | 2 +- manual/tuples/README.md | 8 +-- manual/udts/README.md | 2 +- 38 files changed, 249 insertions(+), 249 deletions(-) diff --git a/README.md b/README.md index 25b0d4754d7..db302c4e2f6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ not yet have been released. You can find the documentation for latest version through [Java driver docs](http://datastax.github.io/java-driver/) or via the release tags, [e.g. -3.3.0](https://github.com/datastax/java-driver/tree/3.3.0).* +3.3.1](https://github.com/datastax/java-driver/tree/3.3.1).* A modern, [feature-rich](manual/) and highly tunable Java client library for Apache Cassandra (1.2+) and DataStax Enterprise (3.1+) using @@ -55,7 +55,7 @@ The driver contains the following modules: start material and technical details about the driver and its features. - API: http://www.datastax.com/drivers/java/3.2 - [changelog](changelog/) -- [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.0.tar.gz) +- [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.1.tar.gz) **Feeback requested:** help us focus our efforts, provide your input on the [Platform and Runtime Survey](http://goo.gl/forms/qwUE6qnL7U) (we kept it short). @@ -68,7 +68,7 @@ it in your application using the following Maven dependency: com.datastax.cassandra cassandra-driver-core - 3.3.0 + 3.3.1 ``` @@ -78,7 +78,7 @@ Note that the object mapper is published as a separate artifact: com.datastax.cassandra cassandra-driver-mapping - 3.3.0 + 3.3.1 ``` @@ -88,7 +88,7 @@ The 'extras' module is also published as a separate artifact: com.datastax.cassandra cassandra-driver-extras - 3.3.0 + 3.3.1 ``` @@ -97,12 +97,12 @@ We also provide a [shaded JAR](manual/shaded_jar/) to avoid the explicit dependency to Netty. If you can't use a dependency management tool, a -[binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.0.tar.gz) +[binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.1.tar.gz) is available for download. ## Compatibility -The Java client driver 3.3.0 ([branch 3.x](https://github.com/datastax/java-driver/tree/3.x)) is compatible with Apache +The Java client driver 3.3.1 ([branch 3.x](https://github.com/datastax/java-driver/tree/3.x)) is compatible with Apache Cassandra 1.2, 2.0, 2.1, 2.2 and 3.0 (see [this page](http://datastax.github.io/java-driver/manual/native_protocol) for the most up-to-date compatibility information). diff --git a/changelog/README.md b/changelog/README.md index 3dade10f0e8..881b98753f2 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,6 +1,6 @@ ## Changelog -### 3.3.1 (In progress) +### 3.3.1 - [bug] JAVA-1555: Include VIEW and CDC in WriteType. - [bug] JAVA-1599: exportAsString improvements (sort, format, clustering order) diff --git a/faq/README.md b/faq/README.md index abd221933a1..d902570f6bf 100644 --- a/faq/README.md +++ b/faq/README.md @@ -35,7 +35,7 @@ row.getBool(0); // this is equivalent row.getBool("applied") Note that, unlike manual inspection, `wasApplied` does not consume the first row. -[wasApplied]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html#wasApplied-- +[wasApplied]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSet.html#wasApplied-- ### What is a parameterized statement and how can I use it? @@ -258,7 +258,7 @@ If properly used, the following log message will be logged at INFO on startup: > Found Netty's native epoll transport in the classpath, but NIO was forced through the FORCE_NIO system property. -[Blobs.java]: https://github.com/datastax/java-driver/tree/3.3.0/driver-examples/src/main/java/com/datastax/driver/examples/datatypes/Blobs.java +[Blobs.java]: https://github.com/datastax/java-driver/tree/3.3.1/driver-examples/src/main/java/com/datastax/driver/examples/datatypes/Blobs.java [CASSANDRA-7304]: https://issues.apache.org/jira/browse/CASSANDRA-7304 [Parameters and Binding]: ../manual/statements/prepared/#parameters-and-binding [Mapper options]: ../manual/object_mapper/using/#mapper-options diff --git a/faq/osgi/README.md b/faq/osgi/README.md index 82de85ac591..0b1d3752c68 100644 --- a/faq/osgi/README.md +++ b/faq/osgi/README.md @@ -157,7 +157,7 @@ it is also normal to see the following log lines when starting the driver: [BND]:http://bnd.bndtools.org/ [Maven bundle plugin]:https://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Maven+Bundle+Plugin+%28BND%29 [OSGi examples repository]:https://github.com/datastax/java-driver-examples-osgi -[without metrics]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.Builder.html#withoutMetrics-- +[without metrics]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.Builder.html#withoutMetrics-- [SLF4J]:http://www.slf4j.org/ [Logback]:http://logback.qos.ch/ [Tycho]:https://eclipse.org/tycho/ diff --git a/manual/README.md b/manual/README.md index 019d9941290..0e8e3c32632 100644 --- a/manual/README.md +++ b/manual/README.md @@ -209,7 +209,7 @@ String firstName = row.getString("first_name"); blob getBytes java.nio.ByteBuffer boolean getBool boolean counter getLong long - date getDate LocalDate + date getDate LocalDate decimal getDecimal java.math.BigDecimal double getDouble double float getFloat float @@ -286,17 +286,17 @@ menu on the left hand side to navigate sub-sections. If you're [browsing the sou github.com](https://github.com/datastax/java-driver/tree/3.x/manual), simply navigate to each sub-directory. -[Cluster]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.html -[Cluster.Builder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.Builder.html -[Initializer]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.Initializer.html -[Session]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html -[ResultSet]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html -[Row]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Row.html -[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/NettyOptions.html -[QueryOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html -[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html -[Host.StateListener]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Host.StateListener.html -[LatencyTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/LatencyTracker.html -[SchemaChangeListener]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SchemaChangeListener.html -[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html -[LocalDate]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/LocalDate.html \ No newline at end of file +[Cluster]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.html +[Cluster.Builder]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.Builder.html +[Initializer]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.Initializer.html +[Session]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html +[ResultSet]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSet.html +[Row]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Row.html +[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/NettyOptions.html +[QueryOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryOptions.html +[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html +[Host.StateListener]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Host.StateListener.html +[LatencyTracker]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/LatencyTracker.html +[SchemaChangeListener]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SchemaChangeListener.html +[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[LocalDate]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/LocalDate.html \ No newline at end of file diff --git a/manual/address_resolution/README.md b/manual/address_resolution/README.md index 619fdf574d3..9613f0be7c5 100644 --- a/manual/address_resolution/README.md +++ b/manual/address_resolution/README.md @@ -102,8 +102,8 @@ private/public switch automatically based on location). -[AddressTranslator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/AddressTranslator.html -[EC2MultiRegionAddressTranslator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/EC2MultiRegionAddressTranslator.html +[AddressTranslator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/AddressTranslator.html +[EC2MultiRegionAddressTranslator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/EC2MultiRegionAddressTranslator.html [cassandra.yaml]: https://docs.datastax.com/en/cassandra/3.x/cassandra/configuration/configCassandra_yaml.html [rpc_address]: https://docs.datastax.com/en/cassandra/3.x/cassandra/configuration/configCassandra_yaml.html?scroll=configCassandra_yaml__rpc_address diff --git a/manual/async/README.md b/manual/async/README.md index abc93059f21..b40f6113c60 100644 --- a/manual/async/README.md +++ b/manual/async/README.md @@ -51,8 +51,8 @@ to the current page, and [fetchMoreResults] to get a future to the next page (see also the section on [paging](../paging/)). Here is a full example: -[getAvailableWithoutFetching]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html#getAvailableWithoutFetching-- -[fetchMoreResults]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html#fetchMoreResults-- +[getAvailableWithoutFetching]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSet.html#getAvailableWithoutFetching-- +[fetchMoreResults]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSet.html#fetchMoreResults-- ```java Statement statement = new SimpleStatement("select * from foo").setFetchSize(20); @@ -134,5 +134,5 @@ There are still a few places where the driver will block internally hasn't been fetched already. [ListenableFuture]: https://github.com/google/guava/wiki/ListenableFutureExplained -[init]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.html#init-- -[query trace]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryTrace.html +[init]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.html#init-- +[query trace]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryTrace.html diff --git a/manual/auth/README.md b/manual/auth/README.md index 430e776fa4b..1a5823913cb 100644 --- a/manual/auth/README.md +++ b/manual/auth/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [AuthProvider].* -[AuthProvider]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/AuthProvider.html \ No newline at end of file +[AuthProvider]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/AuthProvider.html \ No newline at end of file diff --git a/manual/compression/README.md b/manual/compression/README.md index dad0e5e5b94..7bbb89aedbe 100644 --- a/manual/compression/README.md +++ b/manual/compression/README.md @@ -85,4 +85,4 @@ cluster = Cluster.builder() .build(); ``` -[pom]: https://repo1.maven.org/maven2/com/datastax/cassandra/cassandra-driver-parent/3.3.0/cassandra-driver-parent-3.3.0.pom +[pom]: https://repo1.maven.org/maven2/com/datastax/cassandra/cassandra-driver-parent/3.3.1/cassandra-driver-parent-3.3.1.pom diff --git a/manual/custom_codecs/README.md b/manual/custom_codecs/README.md index ead31b9a578..856c368c0fa 100644 --- a/manual/custom_codecs/README.md +++ b/manual/custom_codecs/README.md @@ -446,26 +446,26 @@ Beware that in these cases, the lookup performs in average 10x worse. If perform consider using prepared statements all the time. [JAVA-721]: https://datastax-oss.atlassian.net/browse/JAVA-721 -[TypeCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html -[LocalDate]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/LocalDate.html +[TypeCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html +[LocalDate]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/LocalDate.html [ByteBuffer]: http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html -[serialize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html#serialize-T-com.datastax.driver.core.ProtocolVersion- -[deserialize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html#deserialize-java.nio.ByteBuffer-com.datastax.driver.core.ProtocolVersion- -[TypeCodec.format]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html#format-T- -[TypeCodec.parse]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html#parse-java.lang.String- -[accepts]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TypeCodec.html#accepts-com.datastax.driver.core.DataType- -[CodecRegistry]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/CodecRegistry.html -[CodecNotFoundException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/CodecNotFoundException.html +[serialize]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html#serialize-T-com.datastax.driver.core.ProtocolVersion- +[deserialize]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html#deserialize-java.nio.ByteBuffer-com.datastax.driver.core.ProtocolVersion- +[TypeCodec.format]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html#format-T- +[TypeCodec.parse]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html#parse-java.lang.String- +[accepts]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TypeCodec.html#accepts-com.datastax.driver.core.DataType- +[CodecRegistry]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/CodecRegistry.html +[CodecNotFoundException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/CodecNotFoundException.html [Jackson]: https://github.com/FasterXML/jackson [AbstractType]: https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java -[UserType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/UserType.html -[UDTValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/UDTValue.html -[TupleType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html -[TupleValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleValue.html -[CustomType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/DataType.CustomType.html +[UserType]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/UserType.html +[UDTValue]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/UDTValue.html +[TupleType]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleType.html +[TupleValue]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleValue.html +[CustomType]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/DataType.CustomType.html [TypeToken]: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/reflect/TypeToken.html -[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SimpleStatement.html -[BuiltStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/BuiltStatement.html -[setList]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SettableByIndexData.html#setList-int-java.util.List- -[setSet]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SettableByIndexData.html#setSet-int-java.util.Set- -[setMap]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SettableByIndexData.html#setMap-int-java.util.Map- +[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SimpleStatement.html +[BuiltStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/querybuilder/BuiltStatement.html +[setList]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SettableByIndexData.html#setList-int-java.util.List- +[setSet]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SettableByIndexData.html#setSet-int-java.util.Set- +[setMap]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SettableByIndexData.html#setMap-int-java.util.Map- diff --git a/manual/custom_codecs/extras/README.md b/manual/custom_codecs/extras/README.md index 94454f28b78..9a30f888380 100644 --- a/manual/custom_codecs/extras/README.md +++ b/manual/custom_codecs/extras/README.md @@ -10,7 +10,7 @@ The module is published as a separate Maven artifact: com.datastax.cassandra cassandra-driver-extras - 3.3.0 + 3.3.1 ``` @@ -58,10 +58,10 @@ session.execute("INSERT INTO example (id, t) VALUES (1, ?)", ZonedDateTime.parse("2010-06-30T01:20:47.999+01:00")); ``` -[InstantCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/InstantCodec.html -[LocalDateCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/LocalDateCodec.html -[LocalTimeCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/LocalTimeCodec.html -[ZonedDateTimeCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/ZonedDateTimeCodec.html +[InstantCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/jdk8/InstantCodec.html +[LocalDateCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/jdk8/LocalDateCodec.html +[LocalTimeCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/jdk8/LocalTimeCodec.html +[ZonedDateTimeCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/jdk8/ZonedDateTimeCodec.html [Instant]: https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html [LocalDate]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html [LocalTime]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html @@ -111,10 +111,10 @@ session.execute("INSERT INTO example (id, t) VALUES (1, ?)", DateTime.parse("2010-06-30T01:20:47.999+01:00")); ``` -[InstantCodec_joda]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/joda/InstantCodec.html -[LocalDateCodec_joda]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/joda/LocalDateCodec.html -[LocalTimeCodec_joda]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/joda/LocalTimeCodec.html -[DateTimeCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/joda/DateTimeCodec.html +[InstantCodec_joda]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/joda/InstantCodec.html +[LocalDateCodec_joda]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/joda/LocalDateCodec.html +[LocalTimeCodec_joda]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/joda/LocalTimeCodec.html +[DateTimeCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/joda/DateTimeCodec.html [DateTime]: http://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html [Instant_joda]: http://www.joda.org/joda-time/apidocs/org/joda/time/Instant.html [LocalDate_joda]: http://www.joda.org/joda-time/apidocs/org/joda/time/LocalDate.html @@ -132,8 +132,8 @@ Time can also be expressed as simple durations: There is no extra codec for `time`, because by default the driver already maps that type to a `long` representing the number of nanoseconds since midnight. -[SimpleTimestampCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/date/SimpleTimestampCodec.html -[SimpleDateCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/date/SimpleDateCodec.html +[SimpleTimestampCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/date/SimpleTimestampCodec.html +[SimpleDateCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/date/SimpleDateCodec.html ### Enums @@ -171,8 +171,8 @@ Note that if you registered an `EnumNameCodec` and an `EnumOrdinalCodec` _for th In practice, this is unlikely to happen, because you'll probably stick to a single CQL type for a given enum type; however, if you ever run into that issue, the workaround is to use [prepared statements](../../statements/prepared/), for which the driver knows the CQL type and can pick the exact codec. -[EnumNameCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/enums/EnumNameCodec.html -[EnumOrdinalCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/enums/EnumOrdinalCodec.html +[EnumNameCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/enums/EnumNameCodec.html +[EnumOrdinalCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/enums/EnumOrdinalCodec.html [name]: https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html#name-- [ordinal]: https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html#ordinal-- @@ -217,7 +217,7 @@ session.execute("insert into example (id, owner) values (1, ?)", // owner saved as '{"id":1,"name":"root"}' ``` -[JacksonJsonCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/json/JacksonJsonCodec.html +[JacksonJsonCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/json/JacksonJsonCodec.html [Jackson]: https://github.com/FasterXML/jackson @@ -256,7 +256,7 @@ session.execute("insert into example (id, owner) values (1, ?)", ``` -[Jsr353JsonCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/json/Jsr353JsonCodec.html +[Jsr353JsonCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/json/Jsr353JsonCodec.html [JsonStructure]: https://docs.oracle.com/javaee/7/tutorial/jsonp002.htm @@ -309,7 +309,7 @@ For the same reason, we need to give a type hint when setting "v", in the form o anonymous inner class; we recommend storing these tokens as constants in a utility class, to avoid creating them too often. -[OptionalCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/jdk8/OptionalCodec.html +[OptionalCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/jdk8/OptionalCodec.html [Optional]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html [TypeToken]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/reflect/TypeToken.html @@ -353,7 +353,7 @@ session.execute(pst.bind() See the JDK8 Optional section above for explanations about [TypeToken]. -[OptionalCodec_guava]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/guava/OptionalCodec.html +[OptionalCodec_guava]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/guava/OptionalCodec.html [Optional_guava]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Optional.html @@ -378,9 +378,9 @@ session.execute("insert into example (i, l) values (1, ?)", Package [com.datastax.driver.extras.codecs.arrays][arrays] contains similar codecs for all primitive types, and [ObjectArrayCodec] to map arrays of objects. -[IntArrayCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/arrays/IntArrayCodec.html -[ObjectArrayCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/arrays/ObjectArrayCodec.html -[arrays]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/arrays/package-summary.html +[IntArrayCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/arrays/IntArrayCodec.html +[ObjectArrayCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/arrays/ObjectArrayCodec.html +[arrays]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/arrays/package-summary.html ### Abstract utilities @@ -410,5 +410,5 @@ These two classes are convenient, but since they perform conversions in two step optimal approach. If performance is paramount, it's better to start from scratch and convert your objects to `ByteBuffer` directly. -[MappingCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/MappingCodec.html -[ParsingCodec]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/extras/codecs/ParsingCodec.html +[MappingCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/MappingCodec.html +[ParsingCodec]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/extras/codecs/ParsingCodec.html diff --git a/manual/custom_payloads/README.md b/manual/custom_payloads/README.md index d0b68a677ed..4a2531c18c4 100644 --- a/manual/custom_payloads/README.md +++ b/manual/custom_payloads/README.md @@ -241,8 +241,8 @@ The log message contains a pretty-printed version of the payload itself, and its [CASSANDRA-8553]: https://issues.apache.org/jira/browse/CASSANDRA-8553 [v4spec]: https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec [qh]: https://issues.apache.org/jira/browse/CASSANDRA-6659 -[nhae]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[nhae]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html [chm]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html [immutablemap]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html -[ufe]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/UnsupportedFeatureException.html +[ufe]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/UnsupportedFeatureException.html diff --git a/manual/idempotence/README.md b/manual/idempotence/README.md index 4d2b0816965..61f231133e9 100644 --- a/manual/idempotence/README.md +++ b/manual/idempotence/README.md @@ -125,8 +125,8 @@ broke linearizability by doing a transparent retry at step 6. If linearizability is important for you, you should ensure that lightweight transactions are appropriately flagged as not idempotent. -[isIdempotent]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Statement.html#isIdempotent-- -[setDefaultIdempotence]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setDefaultIdempotence-boolean- -[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/QueryBuilder.html +[isIdempotent]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Statement.html#isIdempotent-- +[setDefaultIdempotence]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryOptions.html#setDefaultIdempotence-boolean- +[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/querybuilder/QueryBuilder.html [linearizability]: https://en.wikipedia.org/wiki/Linearizability#Definition_of_linearizability \ No newline at end of file diff --git a/manual/load_balancing/README.md b/manual/load_balancing/README.md index f6b180ccbf3..b6c5fbcba7c 100644 --- a/manual/load_balancing/README.md +++ b/manual/load_balancing/README.md @@ -295,11 +295,11 @@ For any host, the distance returned by the policy is always the same as its chil Query plans are based on the child policy's, except that hosts that are currently excluded for being too slow are moved to the end of the plan. -[withExclusionThreshold]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withExclusionThreshold-double- -[withMininumMeasurements]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withMininumMeasurements-int- -[withRetryPeriod]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withRetryPeriod-long-java.util.concurrent.TimeUnit- -[withScale]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withScale-long-java.util.concurrent.TimeUnit- -[withUpdateRate]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withUpdateRate-long-java.util.concurrent.TimeUnit- +[withExclusionThreshold]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withExclusionThreshold-double- +[withMininumMeasurements]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withMininumMeasurements-int- +[withRetryPeriod]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withRetryPeriod-long-java.util.concurrent.TimeUnit- +[withScale]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withScale-long-java.util.concurrent.TimeUnit- +[withUpdateRate]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.Builder.html#withUpdateRate-long-java.util.concurrent.TimeUnit- ### Filtering policies @@ -317,15 +317,15 @@ studying the existing implementations first: `RoundRobinPolicy` is a good place complex ones like `DCAwareRoundRobinPolicy`. -[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LoadBalancingPolicy.html -[RoundRobinPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RoundRobinPolicy.html -[DCAwareRoundRobinPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DCAwareRoundRobinPolicy.html -[TokenAwarePolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/TokenAwarePolicy.html -[LatencyAwarePolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LatencyAwarePolicy.html -[HostFilterPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/HostFilterPolicy.html -[WhiteListPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/WhiteListPolicy.html -[HostDistance]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/HostDistance.html -[refreshConnectedHosts]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#refreshConnectedHosts-- -[setMetadataEnabled]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setMetadataEnabled-boolean- -[Statement#getKeyspace]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Statement.html#getKeyspace-- -[Statement#getRoutingKey]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Statement.html#getRoutingKey-- +[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LoadBalancingPolicy.html +[RoundRobinPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RoundRobinPolicy.html +[DCAwareRoundRobinPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DCAwareRoundRobinPolicy.html +[TokenAwarePolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/TokenAwarePolicy.html +[LatencyAwarePolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LatencyAwarePolicy.html +[HostFilterPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/HostFilterPolicy.html +[WhiteListPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/WhiteListPolicy.html +[HostDistance]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/HostDistance.html +[refreshConnectedHosts]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#refreshConnectedHosts-- +[setMetadataEnabled]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryOptions.html#setMetadataEnabled-boolean- +[Statement#getKeyspace]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Statement.html#getKeyspace-- +[Statement#getRoutingKey]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Statement.html#getRoutingKey-- diff --git a/manual/logging/README.md b/manual/logging/README.md index ca200f6d09f..39d6cdd540f 100644 --- a/manual/logging/README.md +++ b/manual/logging/README.md @@ -299,4 +299,4 @@ It also turns on slow query tracing as described above. ``` -[query_logger]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryLogger.html +[query_logger]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryLogger.html diff --git a/manual/metadata/README.md b/manual/metadata/README.md index 4e4fd708ffd..e77748c18fe 100644 --- a/manual/metadata/README.md +++ b/manual/metadata/README.md @@ -4,7 +4,7 @@ The driver maintains global information about the Cassandra cluster it is connected to. It is available via [Cluster#getMetadata()][getMetadata]. -[getMetadata]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.html#getMetadata-- +[getMetadata]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.html#getMetadata-- ### Schema metadata @@ -12,8 +12,8 @@ Use [getKeyspace(String)][getKeyspace] or [getKeyspaces()][getKeyspaces] to get keyspace-level metadata. From there you can access the keyspace's objects (tables, and UDTs and UDFs if relevant). -[getKeyspace]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#getKeyspace-java.lang.String- -[getKeyspaces]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#getKeyspaces-- +[getKeyspace]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#getKeyspace-java.lang.String- +[getKeyspaces]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#getKeyspaces-- #### Refreshes @@ -47,8 +47,8 @@ Note that it is preferable to register a listener only *after* the cluster is fu otherwise the listener could be notified with a great deal of "Added" events as the driver builds the schema metadata from scratch for the first time. -[SchemaChangeListener]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SchemaChangeListener.html -[registerListener]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.html#register-com.datastax.driver.core.SchemaChangeListener- +[SchemaChangeListener]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SchemaChangeListener.html +[registerListener]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.html#register-com.datastax.driver.core.SchemaChangeListener- #### Schema agreement @@ -135,9 +135,9 @@ custom executor). Check out the API docs for the features in this section: -* [withMaxSchemaAgreementWaitSeconds(int)](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Cluster.Builder.html#withMaxSchemaAgreementWaitSeconds-int-) -* [isSchemaInAgreement()](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ExecutionInfo.html#isSchemaInAgreement--) -* [checkSchemaAgreement()](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#checkSchemaAgreement--) +* [withMaxSchemaAgreementWaitSeconds(int)](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Cluster.Builder.html#withMaxSchemaAgreementWaitSeconds-int-) +* [isSchemaInAgreement()](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ExecutionInfo.html#isSchemaInAgreement--) +* [checkSchemaAgreement()](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#checkSchemaAgreement--) ### Token metadata @@ -181,14 +181,14 @@ Starting with Cassandra 2.1.5, this information is available in a system table (see [CASSANDRA-7688](https://issues.apache.org/jira/browse/CASSANDRA-7688)). -[metadata]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html -[getTokenRanges]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#getTokenRanges-- -[getTokenRanges2]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#getTokenRanges-java.lang.String-com.datastax.driver.core.Host- -[getReplicas]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#getReplicas-java.lang.String-com.datastax.driver.core.TokenRange- -[newToken]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#newToken-java.lang.String- -[newTokenRange]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metadata.html#newTokenRange-com.datastax.driver.core.Token-com.datastax.driver.core.Token- -[TokenRange]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TokenRange.html -[getTokens]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Host.html#getTokens-- -[setToken]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BoundStatement.html#setToken-int-com.datastax.driver.core.Token- -[getToken]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Row.html#getToken-int- -[getPKToken]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Row.html#getPartitionKeyToken-- +[metadata]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html +[getTokenRanges]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#getTokenRanges-- +[getTokenRanges2]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#getTokenRanges-java.lang.String-com.datastax.driver.core.Host- +[getReplicas]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#getReplicas-java.lang.String-com.datastax.driver.core.TokenRange- +[newToken]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#newToken-java.lang.String- +[newTokenRange]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metadata.html#newTokenRange-com.datastax.driver.core.Token-com.datastax.driver.core.Token- +[TokenRange]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TokenRange.html +[getTokens]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Host.html#getTokens-- +[setToken]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/BoundStatement.html#setToken-int-com.datastax.driver.core.Token- +[getToken]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Row.html#getToken-int- +[getPKToken]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Row.html#getPartitionKeyToken-- diff --git a/manual/metrics/README.md b/manual/metrics/README.md index 7dc741bc4c9..cf9d34b50c4 100644 --- a/manual/metrics/README.md +++ b/manual/metrics/README.md @@ -9,4 +9,4 @@ TODO cover: - getMetrics() returns null until Cluster initialized --> -[Metrics]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.html \ No newline at end of file +[Metrics]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metrics.html \ No newline at end of file diff --git a/manual/native_protocol/README.md b/manual/native_protocol/README.md index be945e75664..2de03c6c5f1 100644 --- a/manual/native_protocol/README.md +++ b/manual/native_protocol/README.md @@ -63,7 +63,7 @@ All host(s) tried for query failed [/127.0.0.1:9042] Host /127.0.0.1:9042 does not support protocol version V3 but V2)) ``` -[gpv]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- +[gpv]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- #### Protocol version with mixed clusters @@ -94,19 +94,19 @@ To avoid this issue, you can use one the following workarounds: #### v1 to v2 * bound variables in simple statements - ([Session#execute(String, Object...)](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-java.lang.String-java.lang.Object...-)) -* [batch statements](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html) + ([Session#execute(String, Object...)](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#execute-java.lang.String-java.lang.Object...-)) +* [batch statements](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/BatchStatement.html) * [query paging](../paging/) #### v2 to v3 * the number of stream ids per connection goes from 128 to 32768 (see [Connection pooling](../pooling/)) -* [serial consistency on batch statements](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html#setSerialConsistencyLevel-com.datastax.driver.core.ConsistencyLevel-) +* [serial consistency on batch statements](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/BatchStatement.html#setSerialConsistencyLevel-com.datastax.driver.core.ConsistencyLevel-) * [client-side timestamps](../query_timestamps/) #### v3 to v4 -* [query warnings](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ExecutionInfo.html#getWarnings--) +* [query warnings](http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ExecutionInfo.html#getWarnings--) * allowed unset values in bound statements * [Custom payloads](../custom_payloads/) diff --git a/manual/object_mapper/README.md b/manual/object_mapper/README.md index 08e5f18797a..cc8f6901de7 100644 --- a/manual/object_mapper/README.md +++ b/manual/object_mapper/README.md @@ -11,7 +11,7 @@ The mapper is published as a separate Maven artifact: com.datastax.cassandra cassandra-driver-mapping - 3.3.0 + 3.3.1 ``` diff --git a/manual/object_mapper/creating/README.md b/manual/object_mapper/creating/README.md index cbb14bf2244..b5ba962556c 100644 --- a/manual/object_mapper/creating/README.md +++ b/manual/object_mapper/creating/README.md @@ -149,9 +149,9 @@ User user = new User() .setName("John Doe"); ``` -[table]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Table.html +[table]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Table.html [case-sensitive]:http://docs.datastax.com/en/cql/3.3/cql/cql_reference/ucase-lcase_r.html -[consistency level]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ConsistencyLevel.html +[consistency level]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ConsistencyLevel.html [java-beans]:https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html [set-accessible]:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean- @@ -189,7 +189,7 @@ CREATE TABLE users(id uuid PRIMARY KEY, "userName" text); private String userName; ``` -[column]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Column.html +[column]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Column.html #### Primary key fields @@ -213,8 +213,8 @@ private String areaCode; The order of the indices must match that of the columns in the table declaration. -[pk]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/PartitionKey.html -[cc]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/ClusteringColumn.html +[pk]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/PartitionKey.html +[cc]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/ClusteringColumn.html [pks]:http://thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html #### Computed fields @@ -250,7 +250,7 @@ version (see [JAVA-832](https://datastax-oss.atlassian.net/browse/JAVA-832)). [User Defined Functions]:http://www.planetcassandra.org/blog/user-defined-functions-in-cassandra-3-0/ -[computed]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Computed.html +[computed]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Computed.html #### Transient properties @@ -259,7 +259,7 @@ to table columns. [@Transient][transient] can be used to prevent a field or a Java bean property from being mapped. Like other column-level annotations, it should be placed on either the field declaration or the property getter method. -[transient]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Transient.html +[transient]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Transient.html ### Mapping User Types @@ -322,8 +322,8 @@ This also works with UDTs inside collections or other UDTs, with any arbitrary nesting level. [User Defined Types]: ../../udts/ -[udt]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/UDT.html -[field]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Field.html +[udt]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/UDT.html +[field]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Field.html ### Mapping collections @@ -359,9 +359,9 @@ private Map> frozenKeyValueMap; private Map> frozenValueMap; ``` -[frozen]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Frozen.html -[frozenkey]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/FrozenKey.html -[frozenvalue]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/FrozenValue.html +[frozen]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Frozen.html +[frozenkey]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/FrozenKey.html +[frozenvalue]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/FrozenValue.html ### Polymorphism support diff --git a/manual/object_mapper/custom_codecs/README.md b/manual/object_mapper/custom_codecs/README.md index 148164ad115..049aaa0c99f 100644 --- a/manual/object_mapper/custom_codecs/README.md +++ b/manual/object_mapper/custom_codecs/README.md @@ -98,9 +98,9 @@ instance (one per column) and cache it for future use. This also works with [@Field][field] and [@Param][param] annotations. -[column]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Column.html -[field]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Field.html -[param]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Param.html +[column]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Column.html +[field]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Field.html +[param]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Param.html ## Implicit UDT codecs diff --git a/manual/object_mapper/using/README.md b/manual/object_mapper/using/README.md index d802378a28a..137cfe5c7ad 100644 --- a/manual/object_mapper/using/README.md +++ b/manual/object_mapper/using/README.md @@ -28,9 +28,9 @@ Mapper mapper = manager.mapper(User.class); calling `manager#mapper` more than once for the same class will return the previously generated mapper. -[Mapper]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/Mapper.html -[MappingManager]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/MappingManager.html -[Session]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html +[Mapper]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/Mapper.html +[MappingManager]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/MappingManager.html +[Session]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html #### Basic CRUD operations @@ -179,7 +179,7 @@ It provides methods `one()`, `all()`, `iterator()`, `getExecutionInfo()` and `isExhausted()`. Note that iterating the `Result` will consume the `ResultSet`, and vice-versa. -[Result]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/Result.html +[Result]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/Result.html ### Accessors @@ -229,7 +229,7 @@ corresponds to which marker: ResultSet insert(@Param("u") UUID userId, @Param("n") String name); ``` -[param]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Param.html +[param]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/Param.html If a method argument is a Java enumeration, it must be annotated with `@Enumerated` to indicate how to convert it to a CQL type (the rules are @@ -297,7 +297,7 @@ query with the annotation [@QueryParameters]. Then, options like public ListenableFuture> getAllAsync(); ``` -[@QueryParameters]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/QueryParameters.html +[@QueryParameters]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/annotations/QueryParameters.html ### Mapping configuration @@ -341,6 +341,6 @@ PropertyMapper propertyMapper = new DefaultPropertyMapper() There is more to `DefaultPropertyMapper`; see the Javadocs and implementation for details. -[MappingConfiguration]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/MappingConfiguration.html -[PropertyMapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/PropertyMapper.html -[DefaultPropertyMapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/DefaultPropertyMapper.html +[MappingConfiguration]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/MappingConfiguration.html +[PropertyMapper]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/PropertyMapper.html +[DefaultPropertyMapper]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/mapping/DefaultPropertyMapper.html diff --git a/manual/paging/README.md b/manual/paging/README.md index 915600d8099..24925fc619f 100644 --- a/manual/paging/README.md +++ b/manual/paging/README.md @@ -176,8 +176,8 @@ if (nextPage != null) { } ``` -[result_set]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html -[paging_state]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PagingState.html +[result_set]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSet.html +[paging_state]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PagingState.html Due to internal implementation details, `PagingState` instances are not diff --git a/manual/pooling/README.md b/manual/pooling/README.md index f8dbd94bd27..dd2f0872563 100644 --- a/manual/pooling/README.md +++ b/manual/pooling/README.md @@ -283,16 +283,16 @@ either: [newConnectionThreshold][nct] so that enough connections are added by the time you reach the bottleneck. -[result_set_future]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSetFuture.html -[pooling_options]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html -[lbp]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LoadBalancingPolicy.html -[nct]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setNewConnectionThreshold-com.datastax.driver.core.HostDistance-int- -[mrpc]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setMaxRequestsPerConnection-com.datastax.driver.core.HostDistance-int- -[sits]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setIdleTimeoutSeconds-int- -[rtm]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#getReadTimeoutMillis-- -[smqs]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setMaxQueueSize-int- -[sptm]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setPoolTimeoutMillis-int- -[nhae]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html -[getErrors]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- -[get_state]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#getState-- -[BusyPoolException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/BusyPoolException.html +[result_set_future]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ResultSetFuture.html +[pooling_options]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html +[lbp]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LoadBalancingPolicy.html +[nct]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#setNewConnectionThreshold-com.datastax.driver.core.HostDistance-int- +[mrpc]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#setMaxRequestsPerConnection-com.datastax.driver.core.HostDistance-int- +[sits]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#setIdleTimeoutSeconds-int- +[rtm]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#getReadTimeoutMillis-- +[smqs]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#setMaxQueueSize-int- +[sptm]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PoolingOptions.html#setPoolTimeoutMillis-int- +[nhae]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[getErrors]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- +[get_state]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#getState-- +[BusyPoolException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/BusyPoolException.html diff --git a/manual/query_timestamps/README.md b/manual/query_timestamps/README.md index cb3f4dce9cf..de570969869 100644 --- a/manual/query_timestamps/README.md +++ b/manual/query_timestamps/README.md @@ -140,10 +140,10 @@ following: Steps 2 and 3 only apply if native protocol v3 or above is in use. -[TimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TimestampGenerator.html -[AtomicMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/AtomicMonotonicTimestampGenerator.html -[ThreadLocalMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ThreadLocalMonotonicTimestampGenerator.html -[ServerSideTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ServerSideTimestampGenerator.html +[TimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TimestampGenerator.html +[AtomicMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/AtomicMonotonicTimestampGenerator.html +[ThreadLocalMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ThreadLocalMonotonicTimestampGenerator.html +[ServerSideTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ServerSideTimestampGenerator.html [gettimeofday]: http://man7.org/linux/man-pages/man2/settimeofday.2.html [JNR]: https://github.com/jnr/jnr-ffi diff --git a/manual/reconnection/README.md b/manual/reconnection/README.md index ccd4598a309..1d705cbca03 100644 --- a/manual/reconnection/README.md +++ b/manual/reconnection/README.md @@ -8,4 +8,4 @@ TODO cover: - scheduled reconnections vs. gossip events --> -[ReconnectionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/ReconnectionPolicy.html \ No newline at end of file +[ReconnectionPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/ReconnectionPolicy.html \ No newline at end of file diff --git a/manual/retries/README.md b/manual/retries/README.md index a11adb93828..8fa40a2f428 100644 --- a/manual/retries/README.md +++ b/manual/retries/README.md @@ -146,33 +146,33 @@ implementations to handle idempotence (the new behavior is equivalent to what yo `IdempotenceAwareRetryPolicy` before). -[RetryDecision]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html -[retry()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#retry-com.datastax.driver.core.ConsistencyLevel- -[tryNextHost()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#tryNextHost-com.datastax.driver.core.ConsistencyLevel- -[rethrow()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#rethrow-- -[ignore()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#ignore-- -[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html -[getErrors()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- -[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html -[DefaultRetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html -[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- -[onWriteTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onWriteTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.WriteType-int-int-int- -[onUnavailable]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onUnavailable-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-int- -[onRequestError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- -[UnavailableException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/UnavailableException.html -[ReadTimeoutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ReadTimeoutException.html -[WriteTimeoutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/WriteTimeoutException.html -[OverloadedException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OverloadedException.html -[ServerError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ServerError.html -[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OperationTimedOutException.html -[ConnectionException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ConnectionException.html -[QueryValidationException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/QueryValidationException.html -[InvalidQueryException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/InvalidQueryException.html -[InvalidConfigurationInQueryException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/InvalidConfigurationInQueryException.html -[UnauthorizedException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/UnauthorizedException.html -[SyntaxError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/SyntaxError.html -[AlreadyExistsException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/AlreadyExistsException.html -[TruncateException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/TruncateException.html +[RetryDecision]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html +[retry()]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#retry-com.datastax.driver.core.ConsistencyLevel- +[tryNextHost()]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#tryNextHost-com.datastax.driver.core.ConsistencyLevel- +[rethrow()]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#rethrow-- +[ignore()]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#ignore-- +[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[getErrors()]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- +[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.html +[DefaultRetryPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DefaultRetryPolicy.html +[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- +[onWriteTimeout]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onWriteTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.WriteType-int-int-int- +[onUnavailable]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onUnavailable-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-int- +[onRequestError]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- +[UnavailableException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/UnavailableException.html +[ReadTimeoutException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/ReadTimeoutException.html +[WriteTimeoutException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/WriteTimeoutException.html +[OverloadedException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/OverloadedException.html +[ServerError]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/ServerError.html +[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/OperationTimedOutException.html +[ConnectionException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/ConnectionException.html +[QueryValidationException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/QueryValidationException.html +[InvalidQueryException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/InvalidQueryException.html +[InvalidConfigurationInQueryException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/InvalidConfigurationInQueryException.html +[UnauthorizedException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/UnauthorizedException.html +[SyntaxError]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/SyntaxError.html +[AlreadyExistsException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/AlreadyExistsException.html +[TruncateException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/TruncateException.html [query plan]: ../load_balancing/#query-plan [connection pool]: ../pooling/ diff --git a/manual/shaded_jar/README.md b/manual/shaded_jar/README.md index 6319c1a10fb..7a49f2bcb85 100644 --- a/manual/shaded_jar/README.md +++ b/manual/shaded_jar/README.md @@ -12,7 +12,7 @@ package name: com.datastax.cassandra cassandra-driver-core - 3.3.0 + 3.3.1 shaded @@ -32,7 +32,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-core - 3.3.0 + 3.3.1 shaded @@ -44,7 +44,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-mapping - 3.3.0 + 3.3.1 com.datastax.cassandra @@ -74,5 +74,5 @@ detects that shaded Netty classes are being used: Detected shaded Netty classes in the classpath; native epoll transport will not work properly, defaulting to NIO. -[NettyOptions]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/NettyOptions.html +[NettyOptions]:http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/NettyOptions.html [Netty native transports]:http://netty.io/wiki/native-transports.html diff --git a/manual/socket_options/README.md b/manual/socket_options/README.md index 8a0defd87e7..40bef6d7244 100644 --- a/manual/socket_options/README.md +++ b/manual/socket_options/README.md @@ -117,15 +117,15 @@ To clarify: We might rename `SocketOptions.setReadTimeoutMillis` in a future version to clear up any confusion. -[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html -[setReadTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReadTimeoutMillis-int- -[setConnectTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setConnectTimeoutMillis-int- -[setKeepAlive]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setKeepAlive-boolean- -[setReceiveBufferSize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReceiveBufferSize-int- -[setReuseAddress]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReuseAddress-boolean- -[setSendBufferSize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setSendBufferSize-int- -[setSoLinger]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setSoLinger-int- -[setTcpNoDelay]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setTcpNoDelay-boolean- -[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- -[onRequestError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- -[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OperationTimedOutException.html \ No newline at end of file +[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html +[setReadTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setReadTimeoutMillis-int- +[setConnectTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setConnectTimeoutMillis-int- +[setKeepAlive]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setKeepAlive-boolean- +[setReceiveBufferSize]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setReceiveBufferSize-int- +[setReuseAddress]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setReuseAddress-boolean- +[setSendBufferSize]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setSendBufferSize-int- +[setSoLinger]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setSoLinger-int- +[setTcpNoDelay]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SocketOptions.html#setTcpNoDelay-boolean- +[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- +[onRequestError]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- +[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/exceptions/OperationTimedOutException.html \ No newline at end of file diff --git a/manual/speculative_execution/README.md b/manual/speculative_execution/README.md index ceecc2a0f3b..127d440d7bc 100644 --- a/manual/speculative_execution/README.md +++ b/manual/speculative_execution/README.md @@ -73,7 +73,7 @@ Speculative executions are controlled by an instance of `Cluster`. This policy defines the threshold after which a new speculative execution will be triggered. -[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html +[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html Two implementations are provided with the driver: @@ -101,7 +101,7 @@ way: * if no response has been received at t0 + 1000 milliseconds, start another speculative execution on a third node. -[ConstantSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.html +[ConstantSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.html #### [PercentileSpeculativeExecutionPolicy] @@ -160,10 +160,10 @@ Note that `PercentileTracker` may also be used with a slow query logger (see the [Logging](../logging/) section). In that case, you would create a single tracker object and share it with both components. -[PercentileSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/PercentileSpeculativeExecutionPolicy.html -[PercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PercentileTracker.html -[ClusterWidePercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ClusterWidePercentileTracker.html -[PerHostPercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PerHostPercentileTracker.html +[PercentileSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/PercentileSpeculativeExecutionPolicy.html +[PercentileTracker]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PercentileTracker.html +[ClusterWidePercentileTracker]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ClusterWidePercentileTracker.html +[PerHostPercentileTracker]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PerHostPercentileTracker.html [hdr]: http://hdrhistogram.github.io/HdrHistogram/ #### Using your own @@ -210,7 +210,7 @@ client driver exec1 exec2 The only impact is that all executions of the same query always share the same query plan, so each host will be used by at most one execution. -[retry_policy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html +[retry_policy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.html ### Tuning and practical details @@ -225,8 +225,8 @@ You can monitor how many speculative executions were triggered with the It should only be a few percents of the total number of requests ([cluster.getMetrics().getRequestsTimer().getCount()][request_metric]). -[se_metric]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.Errors.html#getSpeculativeExecutions-- -[request_metric]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.html#getRequestsTimer-- +[se_metric]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metrics.Errors.html#getSpeculativeExecutions-- +[request_metric]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Metrics.html#getRequestsTimer-- #### Stream id exhaustion @@ -255,8 +255,8 @@ sustained. If you're unsure of which native protocol version you're using, you can check with [cluster.getConfiguration().getProtocolOptions().getProtocolVersion()][protocol_version]. -[session_state]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.State.html -[protocol_version]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- +[session_state]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.State.html +[protocol_version]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- #### Request ordering and client timestamps diff --git a/manual/ssl/README.md b/manual/ssl/README.md index 59249b586c2..0830c631e92 100644 --- a/manual/ssl/README.md +++ b/manual/ssl/README.md @@ -185,8 +185,8 @@ Cluster cluster = Cluster.builder() .build(); ``` -[RemoteEndpointAwareSSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareSSLOptions.html -[RemoteEndpointAwareJdkSSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html -[newSSLEngine]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html#newSSLEngine-io.netty.channel.socket.SocketChannel-java.net.InetSocketAddress- -[RemoteEndpointAwareNettySSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareNettySSLOptions.html -[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/NettyOptions.html +[RemoteEndpointAwareSSLOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/RemoteEndpointAwareSSLOptions.html +[RemoteEndpointAwareJdkSSLOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html +[newSSLEngine]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html#newSSLEngine-io.netty.channel.socket.SocketChannel-java.net.InetSocketAddress- +[RemoteEndpointAwareNettySSLOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/RemoteEndpointAwareNettySSLOptions.html +[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/NettyOptions.html diff --git a/manual/statements/README.md b/manual/statements/README.md index 6efd14ce104..eeda3170f25 100644 --- a/manual/statements/README.md +++ b/manual/statements/README.md @@ -32,11 +32,11 @@ If you use custom policies ([RetryPolicy], [LoadBalancingPolicy], properties that influence statement execution. To achieve this, you can wrap your statements in a custom [StatementWrapper] implementation. -[Statement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Statement.html -[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/QueryBuilder.html -[StatementWrapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/StatementWrapper.html -[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html -[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LoadBalancingPolicy.html -[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html -[execute]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- -[executeAsync]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- +[Statement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Statement.html +[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/querybuilder/QueryBuilder.html +[StatementWrapper]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/StatementWrapper.html +[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/RetryPolicy.html +[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/LoadBalancingPolicy.html +[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html +[execute]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- +[executeAsync]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- diff --git a/manual/statements/batch/README.md b/manual/statements/batch/README.md index 5f3b7930c32..8ae56c2cb6a 100644 --- a/manual/statements/batch/README.md +++ b/manual/statements/batch/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [BatchStatement].* -[BatchStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html +[BatchStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/BatchStatement.html diff --git a/manual/statements/built/README.md b/manual/statements/built/README.md index 405aa9d2161..93cd430dbb2 100644 --- a/manual/statements/built/README.md +++ b/manual/statements/built/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [QueryBuilder].* -[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/QueryBuilder.html \ No newline at end of file +[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/querybuilder/QueryBuilder.html \ No newline at end of file diff --git a/manual/statements/prepared/README.md b/manual/statements/prepared/README.md index 2132db700ae..4fe8c9558bc 100644 --- a/manual/statements/prepared/README.md +++ b/manual/statements/prepared/README.md @@ -257,11 +257,11 @@ in your statement, i.e.: `SELECT a, b, c FROM tbl`. This will be addressed in a future release of both Cassandra and the driver. Follow [CASSANDRA-10786] and [JAVA-1196] for more information. -[PreparedStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PreparedStatement.html -[BoundStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BoundStatement.html -[setPrepareOnAllHosts]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setPrepareOnAllHosts-boolean- -[setReprepareOnUp]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setReprepareOnUp-boolean- -[execute]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- -[executeAsync]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- +[PreparedStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/PreparedStatement.html +[BoundStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/BoundStatement.html +[setPrepareOnAllHosts]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryOptions.html#setPrepareOnAllHosts-boolean- +[setReprepareOnUp]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/QueryOptions.html#setReprepareOnUp-boolean- +[execute]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- +[executeAsync]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- [CASSANDRA-10786]: https://issues.apache.org/jira/browse/CASSANDRA-10786 [JAVA-1196]: https://datastax-oss.atlassian.net/browse/JAVA-1196 \ No newline at end of file diff --git a/manual/statements/simple/README.md b/manual/statements/simple/README.md index 9967b0e4bf3..4ba119e8854 100644 --- a/manual/statements/simple/README.md +++ b/manual/statements/simple/README.md @@ -128,4 +128,4 @@ session.execute( 1, bytes); ``` -[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SimpleStatement.html +[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/SimpleStatement.html diff --git a/manual/tuples/README.md b/manual/tuples/README.md index 345bcc517ff..6652b81482e 100644 --- a/manual/tuples/README.md +++ b/manual/tuples/README.md @@ -96,7 +96,7 @@ bs.setList("l", Arrays.asList(oneTimeUsageTuple.newValue("1", "1"), oneTimeUsage session.execute(bs); ``` -[TupleType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html -[TupleValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleValue.html -[newValueVararg]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html#newValue-java.lang.Object...- -[newValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html#newValue-- +[TupleType]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleType.html +[TupleValue]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleValue.html +[newValueVararg]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleType.html#newValue-java.lang.Object...- +[newValue]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/TupleType.html#newValue-- diff --git a/manual/udts/README.md b/manual/udts/README.md index 760b87e9321..b04569085ee 100644 --- a/manual/udts/README.md +++ b/manual/udts/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [UserType].* -[UserType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/UserType.html \ No newline at end of file +[UserType]: http://docs.datastax.com/en/drivers/java/3.3/com/datastax/driver/core/UserType.html \ No newline at end of file From cb36007f42eda5c94030c4478d23076aadc3b161 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 7 Nov 2017 13:32:13 -0800 Subject: [PATCH 027/382] [maven-release-plugin] prepare release 3.3.1 --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index dc75330bc85..a2eb614504b 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index 5e78fdeac94..ff62b93597d 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 6493c014516..bef3e04a20e 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index afcc6d863d3..3a847a9976c 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index eba4e610cf4..750278d8848 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index 2616fb75db0..c5cf67e698f 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index dcce75bcfb0..336b6f05a15 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 745cc6aa10e..7232e6c9025 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1-SNAPSHOT + 3.3.1 pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index 61f86f6c5dd..5e417047839 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index aa87180b1f8..aedc248bebc 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index c518ca88c7d..856e5b123c4 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1-SNAPSHOT + 3.3.1 cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index 7939b9d11fc..c02ed9eef68 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1-SNAPSHOT + 3.3.1 pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - HEAD + 3.3.1 From c0a13f184a7ccd27c86a39c6e8ed98ffd666a964 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 7 Nov 2017 13:32:22 -0800 Subject: [PATCH 028/382] [maven-release-plugin] prepare for next development iteration --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index a2eb614504b..2d0034acebb 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index ff62b93597d..e50c6ff6400 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index bef3e04a20e..780f512bd14 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 3a847a9976c..3f2607f21ee 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 750278d8848..68ce7bd2b99 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index c5cf67e698f..bb066034f77 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 336b6f05a15..6a83dbac0bb 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 7232e6c9025..14df05792c5 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1 + 3.3.2-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index 5e417047839..277ef8a6f55 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index aedc248bebc..c2e2e95a1f8 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 856e5b123c4..26c16dc2f5b 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.1 + 3.3.2-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index c02ed9eef68..57a9eb8811a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.1 + 3.3.2-SNAPSHOT pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - 3.3.1 + HEAD From 5920f47e46bc468a1b21d60b8cfeb6616d5f876c Mon Sep 17 00:00:00 2001 From: olim7t Date: Wed, 8 Nov 2017 15:46:47 -0800 Subject: [PATCH 029/382] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names --- changelog/README.md | 5 +++++ .../java/com/datastax/driver/core/KeyspaceMetadata.java | 6 +++--- .../java/com/datastax/driver/core/ExportAsStringTest.java | 2 +- .../src/test/resources/export_as_string_test_2.1.cql | 2 +- .../src/test/resources/export_as_string_test_2.2.cql | 2 +- .../src/test/resources/export_as_string_test_3.0.cql | 2 +- .../src/test/resources/export_as_string_test_3.11.cql | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 881b98753f2..bbbc15a80f2 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,5 +1,10 @@ ## Changelog +### 3.3.2 (in progress) + +- [bug] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names. + + ### 3.3.1 - [bug] JAVA-1555: Include VIEW and CDC in WriteType. diff --git a/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java b/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java index d827cd9fffd..849bb494981 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java @@ -317,10 +317,10 @@ private List getSortedUserTypes() { } private boolean dependsOn(UserType udt1, UserType udt2) { - for (String fieldName : udt1.getFieldNames()) { - DataType fieldType = udt1.getFieldType(fieldName); - if (references(fieldType, udt2)) + for (UserType.Field field : udt1) { + if (references(field.getType(), udt2)) { return true; + } } return false; } diff --git a/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java index 7ebb9e36aef..2576f18b8fa 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java @@ -79,7 +79,7 @@ public void create_schema_and_ensure_exported_cql_is_as_expected() { // Usertype 'ctype' which depends on both ztype and xtype, therefore ztype and xtype should show up earlier. session.execute(SchemaBuilder.createType("ctype") - .addColumn("z", ks.getUserType("ztype").copy(true)) + .addColumn("\"Z\"", ks.getUserType("ztype").copy(true)) .addColumn("x", ks.getUserType("xtype").copy(true))); // Usertype 'btype' which has no dependencies, should show up before 'xtype' and 'ztype' since it's diff --git a/driver-core/src/test/resources/export_as_string_test_2.1.cql b/driver-core/src/test/resources/export_as_string_test_2.1.cql index 0d71991cd70..4e90831a065 100644 --- a/driver-core/src/test/resources/export_as_string_test_2.1.cql +++ b/driver-core/src/test/resources/export_as_string_test_2.1.cql @@ -14,7 +14,7 @@ CREATE TYPE complex_ks.ztype ( ); CREATE TYPE complex_ks.ctype ( - z frozen, + "Z" frozen, x frozen ); diff --git a/driver-core/src/test/resources/export_as_string_test_2.2.cql b/driver-core/src/test/resources/export_as_string_test_2.2.cql index 2789c7ce999..15c4788b767 100644 --- a/driver-core/src/test/resources/export_as_string_test_2.2.cql +++ b/driver-core/src/test/resources/export_as_string_test_2.2.cql @@ -14,7 +14,7 @@ CREATE TYPE complex_ks.ztype ( ); CREATE TYPE complex_ks.ctype ( - z frozen, + "Z" frozen, x frozen ); diff --git a/driver-core/src/test/resources/export_as_string_test_3.0.cql b/driver-core/src/test/resources/export_as_string_test_3.0.cql index 04fe39adc98..f90ec614d7b 100644 --- a/driver-core/src/test/resources/export_as_string_test_3.0.cql +++ b/driver-core/src/test/resources/export_as_string_test_3.0.cql @@ -14,7 +14,7 @@ CREATE TYPE complex_ks.ztype ( ); CREATE TYPE complex_ks.ctype ( - z frozen, + "Z" frozen, x frozen ); diff --git a/driver-core/src/test/resources/export_as_string_test_3.11.cql b/driver-core/src/test/resources/export_as_string_test_3.11.cql index 204d1c58f68..6133df2fa83 100644 --- a/driver-core/src/test/resources/export_as_string_test_3.11.cql +++ b/driver-core/src/test/resources/export_as_string_test_3.11.cql @@ -14,7 +14,7 @@ CREATE TYPE complex_ks.ztype ( ); CREATE TYPE complex_ks.ctype ( - z frozen, + "Z" frozen, x frozen ); From 0461ed357dec050d1310bcd0fdf6094351eaf136 Mon Sep 17 00:00:00 2001 From: Alex Petrov Date: Fri, 3 Jun 2016 09:22:22 +0200 Subject: [PATCH 030/382] JAVA-1196: Include hash of result set metadata in prepared statement id Motivation: See CASSANDRA-10786. When a table is altered (column is added), the wildcard queries keep the old result metadata and never return the added column for all but the very first client (as the very first client is the only one that receives UNPREPARED statement). After adding result metadata to md5 on Cassandra side, as the message metadata on the client is never updated and new client ID of the re-prepared message is not saved anywhere, client would fall into the infinite re-prepare loop. Modifications: With Protocol V5: - Include result metadata id in EXECUTE messages. - Read result metadata id in PREPARED and ROWS responses. - Replace cached prepared statements when result metadata id has changed. Result: Wildcard queries are now safe to use (see JAVA-420). Result metadata id is now correctly handled. --- changelog/README.md | 1 + .../driver/core/ArrayBackedResultSet.java | 80 ++++-- .../datastax/driver/core/BatchStatement.java | 4 +- .../datastax/driver/core/BoundStatement.java | 5 +- .../com/datastax/driver/core/Cluster.java | 4 +- .../driver/core/DefaultPreparedStatement.java | 22 +- .../com/datastax/driver/core/PreparedId.java | 32 ++- .../datastax/driver/core/ProtocolFeature.java | 46 ++++ .../com/datastax/driver/core/Requests.java | 22 +- .../com/datastax/driver/core/Responses.java | 41 ++- .../datastax/driver/core/SessionManager.java | 19 +- .../com/datastax/driver/core/Assertions.java | 4 + .../datastax/driver/core/CCMTestsSupport.java | 15 + .../driver/core/ColumnDefinitionsAssert.java | 47 ++++ .../PreparedStatementInvalidationTest.java | 256 ++++++++++++++++++ 15 files changed, 532 insertions(+), 66 deletions(-) create mode 100644 driver-core/src/main/java/com/datastax/driver/core/ProtocolFeature.java create mode 100644 driver-core/src/test/java/com/datastax/driver/core/ColumnDefinitionsAssert.java create mode 100644 driver-core/src/test/java/com/datastax/driver/core/PreparedStatementInvalidationTest.java diff --git a/changelog/README.md b/changelog/README.md index bbbc15a80f2..112c13942f3 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -3,6 +3,7 @@ ### 3.3.2 (in progress) - [bug] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names. +- [improvement] JAVA-1196: Include hash of result set metadata in prepared statement id. ### 3.3.1 diff --git a/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java b/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java index 0bf225eed90..81e348afb4c 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java @@ -39,7 +39,7 @@ abstract class ArrayBackedResultSet implements ResultSet { private static final Queue> EMPTY_QUEUE = new ArrayDeque>(0); - protected final ColumnDefinitions metadata; + protected volatile ColumnDefinitions metadata; protected final Token.Factory tokenFactory; private final boolean wasApplied; @@ -60,18 +60,42 @@ static ArrayBackedResultSet fromMessage(Responses.Result msg, SessionManager ses case ROWS: Responses.Result.Rows r = (Responses.Result.Rows) msg; - ColumnDefinitions columnDefs; - if (r.metadata.columns == null) { - Statement actualStatement = statement; - if (statement instanceof StatementWrapper) { - actualStatement = ((StatementWrapper) statement).getWrappedStatement(); - } - assert actualStatement instanceof BoundStatement; - columnDefs = ((BoundStatement) actualStatement).statement.getPreparedId().resultSetMetadata; - assert columnDefs != null; + Statement actualStatement = statement; + if (statement instanceof StatementWrapper) { + actualStatement = ((StatementWrapper) statement).getWrappedStatement(); + } + + ColumnDefinitions columnDefs = r.metadata.columns; + if (columnDefs == null) { + // If result set metadata is not present, it means the request had SKIP_METADATA set, the driver + // only ever does that for bound statements. + BoundStatement bs = (BoundStatement) actualStatement; + columnDefs = bs.preparedStatement().getPreparedId().resultSetMetadata.variables; } else { - columnDefs = r.metadata.columns; + // Otherwise, always use the response's metadata. + // In addition, if a new id is present it means we're executing a bound statement with protocol v5, + // the schema changed server-side, and we need to update the prepared statement (see + // CASSANDRA-10786). + MD5Digest newMetadataId = r.metadata.metadataId; + assert !(actualStatement instanceof BoundStatement) || + ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(protocolVersion) || + newMetadataId == null; + if (newMetadataId != null) { + BoundStatement bs = ((BoundStatement) actualStatement); + PreparedId preparedId = bs.preparedStatement().getPreparedId(); + // Extra test for CASSANDRA-13992: conditional updates yield a different result set depending on + // whether the update was applied or not, so the prepared statement must never have result + // metadata, and we should always execute with skip_metadata = false. + // However the server sends a new_metadata_id in the response, so make sure we ignore it if the + // prepared statement did not have metadata in the first place. + // TODO remove the "if" (i.e. always assign resultSetMetadata) if CASSANDRA-13992 gets fixed before 4.0.0 GA + if (preparedId.resultSetMetadata.variables != null) { + preparedId.resultSetMetadata = + new PreparedId.PreparedMetadata(newMetadataId, columnDefs); + } + } } + assert columnDefs != null; Token.Factory tokenFactory = (session == null) ? null : session.getCluster().manager.metadata.tokenFactory(); @@ -224,7 +248,7 @@ public List getAllExecutionInfo() { private static class MultiPage extends ArrayBackedResultSet { private Queue> currentPage; - private final Queue>> nextPages = new ConcurrentLinkedQueue>>(); + private final Queue nextPages = new ConcurrentLinkedQueue(); private final Deque infos = new LinkedBlockingDeque(); @@ -280,8 +304,8 @@ public Row one() { @Override public int getAvailableWithoutFetching() { int available = currentPage.size(); - for (Queue> page : nextPages) - available += page.size(); + for (NextPage page : nextPages) + available += page.data.size(); return available; } @@ -297,9 +321,12 @@ private void prepareNextRow() { // Grab the current state now to get a consistent view in this iteration. FetchingState fetchingState = this.fetchState; - Queue> nextPage = nextPages.poll(); + NextPage nextPage = nextPages.poll(); if (nextPage != null) { - currentPage = nextPage; + if (nextPage.metadata != null) { + this.metadata = nextPage.metadata; + } + currentPage = nextPage.data; continue; } if (fetchingState == null) @@ -363,7 +390,16 @@ public void onSet(Connection connection, Message.Response response, ExecutionInf if (rm.kind == Responses.Result.Kind.ROWS) { Responses.Result.Rows rows = (Responses.Result.Rows) rm; info = update(info, rm, MultiPage.this.session, rows.metadata.pagingState, protocolVersion, codecRegistry, statement); - MultiPage.this.nextPages.offer(rows.data); + // If the query is a prepared 'SELECT *', the metadata can change between pages + ColumnDefinitions newMetadata = null; + if (rows.metadata.metadataId != null) { + newMetadata = rows.metadata.columns; + assert statement instanceof BoundStatement; + BoundStatement bs = (BoundStatement) statement; + bs.preparedStatement().getPreparedId().resultSetMetadata = + new PreparedId.PreparedMetadata(rows.metadata.metadataId, rows.metadata.columns); + } + MultiPage.this.nextPages.offer(new NextPage(newMetadata, rows.data)); MultiPage.this.fetchState = rows.metadata.pagingState == null ? null : new FetchingState(rows.metadata.pagingState, null); } else if (rm.kind == Responses.Result.Kind.VOID) { // We shouldn't really get a VOID message here but well, no harm in handling it I suppose @@ -443,6 +479,16 @@ private static class FetchingState { this.inProgress = inProgress; } } + + private static class NextPage { + final ColumnDefinitions metadata; + final Queue> data; + + NextPage(ColumnDefinitions metadata, Queue> data) { + this.metadata = metadata; + this.data = data; + } + } } // This method checks the value of the "[applied]" column manually, to avoid instantiating an ArrayBackedRow diff --git a/driver-core/src/main/java/com/datastax/driver/core/BatchStatement.java b/driver-core/src/main/java/com/datastax/driver/core/BatchStatement.java index 481798a7174..e820311895a 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/BatchStatement.java +++ b/driver-core/src/main/java/com/datastax/driver/core/BatchStatement.java @@ -61,8 +61,6 @@ public enum Type { COUNTER } - ; - final Type batchType; private final List statements = new ArrayList(); @@ -97,7 +95,7 @@ IdAndValues getIdAndValues(ProtocolVersion protocolVersion, CodecRegistry codecR // We handle BatchStatement in add() so ... assert statement instanceof BoundStatement; BoundStatement st = (BoundStatement) statement; - idAndVals.ids.add(st.statement.getPreparedId().id); + idAndVals.ids.add(st.statement.getPreparedId().boundValuesMetadata.id); idAndVals.values.add(Arrays.asList(st.wrapper.values)); } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/BoundStatement.java b/driver-core/src/main/java/com/datastax/driver/core/BoundStatement.java index 45264e81165..8855fa994ff 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/BoundStatement.java +++ b/driver-core/src/main/java/com/datastax/driver/core/BoundStatement.java @@ -293,7 +293,10 @@ public BoundStatement setRoutingKey(ByteBuffer... routingKeyComponents) { */ @Override public String getKeyspace() { - return statement.getPreparedId().metadata.size() == 0 ? null : statement.getPreparedId().metadata.getKeyspace(0); + ColumnDefinitions defs = statement.getPreparedId().boundValuesMetadata.variables; + return defs.size() == 0 + ? null + : defs.getKeyspace(0); } /** diff --git a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java index ce4cb89dfd4..145100f0ccb 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java @@ -2218,13 +2218,15 @@ public void ensurePoolsSizing() { } public PreparedStatement addPrepared(PreparedStatement stmt) { - PreparedStatement previous = preparedQueries.putIfAbsent(stmt.getPreparedId().id, stmt); + PreparedStatement previous = preparedQueries.putIfAbsent(stmt.getPreparedId().boundValuesMetadata.id, stmt); if (previous != null) { logger.warn("Re-preparing already prepared query is generally an anti-pattern and will likely affect performance. " + "Consider preparing the statement only once. Query='{}'", stmt.getQueryString()); // The one object in the cache will get GCed once it's not referenced by the client anymore since we use a weak reference. // So we need to make sure that the instance we do return to the user is the one that is in the cache. + // However if the result metadata changed since the last PREPARE call, this also needs to be updated. + previous.getPreparedId().resultSetMetadata = stmt.getPreparedId().resultSetMetadata; return previous; } return stmt; diff --git a/driver-core/src/main/java/com/datastax/driver/core/DefaultPreparedStatement.java b/driver-core/src/main/java/com/datastax/driver/core/DefaultPreparedStatement.java index 9680664944b..2a4ca95ae5c 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/DefaultPreparedStatement.java +++ b/driver-core/src/main/java/com/datastax/driver/core/DefaultPreparedStatement.java @@ -56,18 +56,18 @@ static DefaultPreparedStatement fromMessage(Responses.Result.Prepared msg, Clust ColumnDefinitions defs = msg.metadata.columns; ProtocolVersion protocolVersion = cluster.getConfiguration().getProtocolOptions().getProtocolVersion(); - - if (defs.size() == 0) { - return new DefaultPreparedStatement(new PreparedId(msg.statementId, defs, msg.resultMetadata.columns, null, protocolVersion), query, queryKeyspace, msg.getCustomPayload(), cluster); + PreparedId.PreparedMetadata boundValuesMetadata = new PreparedId.PreparedMetadata(msg.statementId, defs); + PreparedId.PreparedMetadata resultSetMetadata = new PreparedId.PreparedMetadata(msg.resultMetadataId, msg.resultMetadata.columns); + + int[] pkIndices = null; + if (defs.size() > 0) { + pkIndices = (protocolVersion.compareTo(V4) >= 0) + ? msg.metadata.pkIndices + : computePkIndices(cluster.getMetadata(), defs); } - int[] pkIndices = (protocolVersion.compareTo(V4) >= 0) - ? msg.metadata.pkIndices - : computePkIndices(cluster.getMetadata(), defs); - - PreparedId prepId = new PreparedId(msg.statementId, defs, msg.resultMetadata.columns, pkIndices, protocolVersion); - - return new DefaultPreparedStatement(prepId, query, queryKeyspace, msg.getCustomPayload(), cluster); + PreparedId preparedId = new PreparedId(boundValuesMetadata, resultSetMetadata, pkIndices, protocolVersion); + return new DefaultPreparedStatement(preparedId, query, queryKeyspace, msg.getCustomPayload(), cluster); } private static int[] computePkIndices(Metadata clusterMetadata, ColumnDefinitions boundColumns) { @@ -117,7 +117,7 @@ private static boolean allSet(int[] pkColumns) { @Override public ColumnDefinitions getVariables() { - return preparedId.metadata; + return preparedId.boundValuesMetadata.variables; } @Override diff --git a/driver-core/src/main/java/com/datastax/driver/core/PreparedId.java b/driver-core/src/main/java/com/datastax/driver/core/PreparedId.java index 9a0e255f380..3e297231254 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/PreparedId.java +++ b/driver-core/src/main/java/com/datastax/driver/core/PreparedId.java @@ -19,21 +19,37 @@ * Identifies a PreparedStatement. */ public class PreparedId { - // This class is mostly here to group PreparedStatement data that are need for - // execution but that we don't want to expose publicly (see JAVA-195) - final MD5Digest id; - final ColumnDefinitions metadata; - final ColumnDefinitions resultSetMetadata; + // This class is mostly here to group PreparedStatement data that are needed for + // execution but that we don't want to expose publicly (see JAVA-195) final int[] routingKeyIndexes; + final ProtocolVersion protocolVersion; - PreparedId(MD5Digest id, ColumnDefinitions metadata, ColumnDefinitions resultSetMetadata, int[] routingKeyIndexes, ProtocolVersion protocolVersion) { - this.id = id; - this.metadata = metadata; + final PreparedMetadata boundValuesMetadata; + + // can change over time, see JAVA-1196, JAVA-420 + volatile PreparedMetadata resultSetMetadata; + + PreparedId(PreparedMetadata boundValuesMetadata, PreparedMetadata resultSetMetadata, int[] routingKeyIndexes, ProtocolVersion protocolVersion) { + assert boundValuesMetadata != null; + assert resultSetMetadata != null; + this.boundValuesMetadata = boundValuesMetadata; this.resultSetMetadata = resultSetMetadata; this.routingKeyIndexes = routingKeyIndexes; this.protocolVersion = protocolVersion; } + + + static class PreparedMetadata { + + final MD5Digest id; + final ColumnDefinitions variables; + + PreparedMetadata(MD5Digest id, ColumnDefinitions variables) { + this.id = id; + this.variables = variables; + } + } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/ProtocolFeature.java b/driver-core/src/main/java/com/datastax/driver/core/ProtocolFeature.java new file mode 100644 index 00000000000..bbedf6e9084 --- /dev/null +++ b/driver-core/src/main/java/com/datastax/driver/core/ProtocolFeature.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +/** + * A listing of features that may or not apply to a given {@link ProtocolVersion}. + */ +enum ProtocolFeature { + + /** + * The capability of updating a prepared statement if the result's metadata changes at runtime (for example, if the + * query is a {@code SELECT *} and the table is altered). + */ + PREPARED_METADATA_CHANGES, + // + ; + + /** + * Determines whether or not the input version supports ths feature. + * + * @param version the version to test against. + * @return true if supported, false otherwise. + */ + boolean isSupportedBy(ProtocolVersion version) { + switch (this) { + case PREPARED_METADATA_CHANGES: + return version == ProtocolVersion.V5; + default: + return false; + } + } + +} diff --git a/driver-core/src/main/java/com/datastax/driver/core/Requests.java b/driver-core/src/main/java/com/datastax/driver/core/Requests.java index a4b69d2e284..3af73f4d9b8 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Requests.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Requests.java @@ -183,38 +183,48 @@ static class Execute extends Message.Request { @Override public void encode(Execute msg, ByteBuf dest, ProtocolVersion version) { CBUtil.writeBytes(msg.statementId.bytes, dest); + if (ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(version)) + CBUtil.writeBytes(msg.resultMetadataId.bytes, dest); msg.options.encode(dest, version); } @Override public int encodedSize(Execute msg, ProtocolVersion version) { - return CBUtil.sizeOfBytes(msg.statementId.bytes) - + msg.options.encodedSize(version); + int size = CBUtil.sizeOfBytes(msg.statementId.bytes); + if (ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(version)) + size += CBUtil.sizeOfBytes(msg.resultMetadataId.bytes); + size += msg.options.encodedSize(version); + return size; } }; final MD5Digest statementId; + final MD5Digest resultMetadataId; final QueryProtocolOptions options; - Execute(MD5Digest statementId, QueryProtocolOptions options, boolean tracingRequested) { + Execute(MD5Digest statementId, MD5Digest resultMetadataId, QueryProtocolOptions options, boolean tracingRequested) { super(Message.Request.Type.EXECUTE, tracingRequested); this.statementId = statementId; + this.resultMetadataId = resultMetadataId; this.options = options; } @Override protected Request copyInternal() { - return new Execute(statementId, options, isTracingRequested()); + return new Execute(statementId, resultMetadataId, options, isTracingRequested()); } @Override protected Request copyInternal(ConsistencyLevel newConsistencyLevel) { - return new Execute(statementId, options.copy(newConsistencyLevel), isTracingRequested()); + return new Execute(statementId, resultMetadataId, options.copy(newConsistencyLevel), isTracingRequested()); } @Override public String toString() { - return "EXECUTE " + statementId + " (" + options + ')'; + if (resultMetadataId != null) + return "EXECUTE preparedId: " + statementId + " resultMetadataId: " + resultMetadataId + " (" + options + ')'; + else + return "EXECUTE preparedId: " + statementId + " (" + options + ')'; } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/Responses.java b/driver-core/src/main/java/com/datastax/driver/core/Responses.java index cecd1e1ae9f..847a812eb93 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Responses.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Responses.java @@ -25,7 +25,6 @@ import java.nio.ByteBuffer; import java.util.*; -import static com.datastax.driver.core.ProtocolVersion.V4; import static com.datastax.driver.core.SchemaElement.*; class Responses { @@ -347,7 +346,8 @@ private enum Flag { // The order of that enum matters!! GLOBAL_TABLES_SPEC, HAS_MORE_PAGES, - NO_METADATA; + NO_METADATA, + METADATA_CHANGED; static EnumSet deserialize(int flags) { EnumSet set = EnumSet.noneOf(Flag.class); @@ -367,14 +367,16 @@ static int serialize(EnumSet flags) { } } - static final Metadata EMPTY = new Metadata(0, null, null, null); + static final Metadata EMPTY = new Metadata(null, 0, null, null, null); final int columnCount; final ColumnDefinitions columns; // Can be null if no metadata was asked by the query final ByteBuffer pagingState; final int[] pkIndices; + final MD5Digest metadataId; // only present if the flag METADATA_CHANGED is set (ROWS response only) - private Metadata(int columnCount, ColumnDefinitions columns, ByteBuffer pagingState, int[] pkIndices) { + private Metadata(MD5Digest metadataId, int columnCount, ColumnDefinitions columns, ByteBuffer pagingState, int[] pkIndices) { + this.metadataId = metadataId; this.columnCount = columnCount; this.columns = columns; this.pagingState = pagingState; @@ -391,6 +393,18 @@ static Metadata decode(ByteBuf body, boolean withPkIndices, ProtocolVersion prot EnumSet flags = Flag.deserialize(body.readInt()); int columnCount = body.readInt(); + ByteBuffer state = null; + if (flags.contains(Flag.HAS_MORE_PAGES)) + state = CBUtil.readValue(body); + + MD5Digest resultMetadataId = null; + if (flags.contains(Flag.METADATA_CHANGED)) { + assert ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(protocolVersion) + : "METADATA_CHANGED flag is not supported in protocol version " + protocolVersion; + assert !flags.contains(Flag.NO_METADATA) : "METADATA_CHANGED and NO_METADATA are mutually exclusive flags"; + resultMetadataId = MD5Digest.wrap(CBUtil.readBytes(body)); + } + int[] pkIndices = null; int pkCount; if (withPkIndices && (pkCount = body.readInt()) > 0) { @@ -399,12 +413,8 @@ static Metadata decode(ByteBuf body, boolean withPkIndices, ProtocolVersion prot pkIndices[i] = (int) body.readShort(); } - ByteBuffer state = null; - if (flags.contains(Flag.HAS_MORE_PAGES)) - state = CBUtil.readValue(body); - if (flags.contains(Flag.NO_METADATA)) - return new Metadata(columnCount, null, state, pkIndices); + return new Metadata(resultMetadataId, columnCount, null, state, pkIndices); boolean globalTablesSpec = flags.contains(Flag.GLOBAL_TABLES_SPEC); @@ -425,7 +435,7 @@ static Metadata decode(ByteBuf body, boolean withPkIndices, ProtocolVersion prot defs[i] = new ColumnDefinitions.Definition(ksName, cfName, name, type); } - return new Metadata(columnCount, new ColumnDefinitions(defs, codecRegistry), state, pkIndices); + return new Metadata(resultMetadataId, columnCount, new ColumnDefinitions(defs, codecRegistry), state, pkIndices); } @Override @@ -517,10 +527,13 @@ static class Prepared extends Result { @Override public Result decode(ByteBuf body, ProtocolVersion version, CodecRegistry codecRegistry) { MD5Digest id = MD5Digest.wrap(CBUtil.readBytes(body)); - boolean withPkIndices = version.compareTo(V4) >= 0; + MD5Digest resultMetadataId = null; + if (ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(version)) + resultMetadataId = MD5Digest.wrap(CBUtil.readBytes(body)); + boolean withPkIndices = version.compareTo(ProtocolVersion.V4) >= 0; Rows.Metadata metadata = Rows.Metadata.decode(body, withPkIndices, version, codecRegistry); Rows.Metadata resultMetadata = decodeResultMetadata(body, version, codecRegistry); - return new Prepared(id, metadata, resultMetadata); + return new Prepared(id, resultMetadataId, metadata, resultMetadata); } private Metadata decodeResultMetadata(ByteBuf body, ProtocolVersion version, CodecRegistry codecRegistry) { @@ -539,12 +552,14 @@ private Metadata decodeResultMetadata(ByteBuf body, ProtocolVersion version, Cod }; final MD5Digest statementId; + final MD5Digest resultMetadataId; final Rows.Metadata metadata; final Rows.Metadata resultMetadata; - private Prepared(MD5Digest statementId, Rows.Metadata metadata, Rows.Metadata resultMetadata) { + private Prepared(MD5Digest statementId, MD5Digest resultMetadataId, Rows.Metadata metadata, Rows.Metadata resultMetadata) { super(Kind.PREPARED); this.statementId = statementId; + this.resultMetadataId = resultMetadataId; this.metadata = metadata; this.resultMetadata = resultMetadata; } diff --git a/driver-core/src/main/java/com/datastax/driver/core/SessionManager.java b/driver-core/src/main/java/com/datastax/driver/core/SessionManager.java index 6b56248f69a..0dd9aecb064 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/SessionManager.java +++ b/driver-core/src/main/java/com/datastax/driver/core/SessionManager.java @@ -574,16 +574,23 @@ else if (fetchSize != Integer.MAX_VALUE) request = new Requests.Query(qString, options, statement.isTracing()); } else if (statement instanceof BoundStatement) { BoundStatement bs = (BoundStatement) statement; - if (!cluster.manager.preparedQueries.containsKey(bs.statement.getPreparedId().id)) { + if (!cluster.manager.preparedQueries.containsKey(bs.statement.getPreparedId().boundValuesMetadata.id)) { throw new InvalidQueryException(String.format("Tried to execute unknown prepared query : %s. " - + "You may have used a PreparedStatement that was created with another Cluster instance.", bs.statement.getPreparedId().id)); + + "You may have used a PreparedStatement that was created with another Cluster instance.", bs.statement.getPreparedId().boundValuesMetadata.id)); } if (protocolVersion.compareTo(ProtocolVersion.V4) < 0) bs.ensureAllSet(); - boolean skipMetadata = protocolVersion != ProtocolVersion.V1 && bs.statement.getPreparedId().resultSetMetadata != null; - Requests.QueryProtocolOptions options = new Requests.QueryProtocolOptions(Message.Request.Type.EXECUTE, consistency, Arrays.asList(bs.wrapper.values), Collections.emptyMap(), - skipMetadata, fetchSize, usedPagingState, serialConsistency, defaultTimestamp); - request = new Requests.Execute(bs.statement.getPreparedId().id, options, statement.isTracing()); + + // skip resultset metadata if version > 1 (otherwise this feature is not supported) + // and if we already have metadata for the prepared statement being executed. + boolean skipMetadata = protocolVersion != ProtocolVersion.V1 && bs.statement.getPreparedId().resultSetMetadata.variables != null; + Requests.QueryProtocolOptions options = new Requests.QueryProtocolOptions(Message.Request.Type.EXECUTE, + consistency, Arrays.asList(bs.wrapper.values), Collections.emptyMap(), skipMetadata, + fetchSize, usedPagingState, serialConsistency, defaultTimestamp); + request = new Requests.Execute( + bs.statement.getPreparedId().boundValuesMetadata.id, + bs.statement.getPreparedId().resultSetMetadata.id, + options, statement.isTracing()); } else { assert statement instanceof BatchStatement : statement; assert pagingState == null; diff --git a/driver-core/src/test/java/com/datastax/driver/core/Assertions.java b/driver-core/src/test/java/com/datastax/driver/core/Assertions.java index 86ecc081c14..d86a1090e7c 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/Assertions.java +++ b/driver-core/src/test/java/com/datastax/driver/core/Assertions.java @@ -87,8 +87,12 @@ public static MaterializedViewMetadataAssert assertThat(MaterializedViewMetadata public static VersionNumberAssert assertThat(VersionNumber actual) { return new VersionNumberAssert(actual); } + public static ResultSetAssert assertThat(ResultSet rows) { return new ResultSetAssert(rows); } + public static ColumnDefinitionsAssert assertThat(ColumnDefinitions variables) { + return new ColumnDefinitionsAssert(variables); + } } diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java index 45ac66b91b7..6046c0ce747 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java @@ -1015,6 +1015,21 @@ public void run() { keyspace = null; } + protected void resetTestSession() throws Exception { + session.close(); + Cluster.Builder builder = ccmTestConfig.clusterProvider(this); + // add contact points only if the provided builder didn't do so + if (builder.getContactPoints().isEmpty()) + builder.addContactPoints(getContactPoints()); + builder.withPort(ccm.getBinaryPort()); + cluster = register(builder.build()); + cluster.init(); + + session.close(); + session = register(cluster.connect()); + useKeyspace(session, keyspace); + } + protected void closeCloseables() { if (closer != null) executeNoFail(new Callable() { diff --git a/driver-core/src/test/java/com/datastax/driver/core/ColumnDefinitionsAssert.java b/driver-core/src/test/java/com/datastax/driver/core/ColumnDefinitionsAssert.java new file mode 100644 index 00000000000..4f94bead04c --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/ColumnDefinitionsAssert.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import org.assertj.core.api.AbstractAssert; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +public class ColumnDefinitionsAssert extends AbstractAssert { + + public ColumnDefinitionsAssert(ColumnDefinitions actual) { + super(actual, ColumnDefinitionsAssert.class); + } + + public ColumnDefinitionsAssert hasSize(int expected) { + assertThat(actual.size()).isEqualTo(expected); + return this; + } + + public ColumnDefinitionsAssert containsVariable(String name, DataType type) { + try { + assertThat(actual.getType(name)).isEqualTo(type); + } catch (Exception e) { + fail(String.format("Expected actual to contain variable %s of type %s, but it did not", name, type), e); + } + return this; + } + + public ColumnDefinitionsAssert doesNotContainVariable(String name) { + assertThat(actual.getIndexOf(name)).isEqualTo(-1); + return this; + } +} diff --git a/driver-core/src/test/java/com/datastax/driver/core/PreparedStatementInvalidationTest.java b/driver-core/src/test/java/com/datastax/driver/core/PreparedStatementInvalidationTest.java new file mode 100644 index 00000000000..2d707777f12 --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/PreparedStatementInvalidationTest.java @@ -0,0 +1,256 @@ + +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + + +import com.datastax.driver.core.exceptions.NoHostAvailableException; +import com.datastax.driver.core.utils.CassandraVersion; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static com.datastax.driver.core.Assertions.assertThat; +import static junit.framework.TestCase.fail; + +/** + * Note: at the time of writing, this test exercises features of an unreleased Cassandra version. To + * test against a local build, run with + * + *

+ *   -Dcassandra.version=4.0.0 -Dcassandra.directory=/path/to/cassandra
+ * 
+ */ +@CassandraVersion("4.0") +public class PreparedStatementInvalidationTest extends CCMTestsSupport { + + @Override + public Cluster.Builder createClusterBuilder() { + // TODO remove when protocol v5 is stable in C* 4 + return super.createClusterBuilderNoDebouncing().allowBetaProtocolVersion(); + } + + @BeforeMethod(groups = "short", alwaysRun = true) + public void setup() throws Exception { + execute("CREATE TABLE prepared_statement_invalidation_test (a int PRIMARY KEY, b int, c int);"); + execute("INSERT INTO prepared_statement_invalidation_test (a, b, c) VALUES (1, 1, 1);"); + execute("INSERT INTO prepared_statement_invalidation_test (a, b, c) VALUES (2, 2, 2);"); + execute("INSERT INTO prepared_statement_invalidation_test (a, b, c) VALUES (3, 3, 3);"); + execute("INSERT INTO prepared_statement_invalidation_test (a, b, c) VALUES (4, 4, 4);"); + } + + @AfterMethod(groups = "short", alwaysRun = true) + public void teardown() throws Exception { + execute("DROP TABLE prepared_statement_invalidation_test"); + } + + @Test(groups = "short") + public void should_update_statement_id_when_metadata_changed_across_executions() { + // given + PreparedStatement ps = session().prepare("SELECT * FROM prepared_statement_invalidation_test WHERE a = ?"); + MD5Digest idBefore = ps.getPreparedId().resultSetMetadata.id; + // when + session().execute("ALTER TABLE prepared_statement_invalidation_test ADD d int"); + BoundStatement bs = ps.bind(1); + ResultSet rows = session().execute(bs); + // then + MD5Digest idAfter = ps.getPreparedId().resultSetMetadata.id; + assertThat(idBefore).isNotEqualTo(idAfter); + assertThat(ps.getPreparedId().resultSetMetadata.variables) + .hasSize(4) + .containsVariable("d", DataType.cint()); + assertThat(bs.preparedStatement().getPreparedId().resultSetMetadata.variables) + .hasSize(4) + .containsVariable("d", DataType.cint()); + assertThat(rows.getColumnDefinitions()) + .hasSize(4) + .containsVariable("d", DataType.cint()); + } + + @Test(groups = "short") + public void should_update_statement_id_when_metadata_changed_across_pages() throws Exception { + // given + PreparedStatement ps = session().prepare("SELECT * FROM prepared_statement_invalidation_test"); + ResultSet rows = session().execute(ps.bind().setFetchSize(2)); + assertThat(rows.isFullyFetched()).isFalse(); + MD5Digest idBefore = ps.getPreparedId().resultSetMetadata.id; + ColumnDefinitions definitionsBefore = rows.getColumnDefinitions(); + assertThat(definitionsBefore) + .hasSize(3) + .doesNotContainVariable("d"); + // consume the first page + int remaining = rows.getAvailableWithoutFetching(); + while (remaining-- > 0) { + try { + rows.one().getInt("d"); + fail("expected an error"); + } catch (IllegalArgumentException e) { /*expected*/ } + } + + // when + session().execute("ALTER TABLE prepared_statement_invalidation_test ADD d int"); + + // then + // this should trigger a background fetch of the second page, and therefore update the definitions + for (Row row : rows) { + assertThat(row.isNull("d")).isTrue(); + } + MD5Digest idAfter = ps.getPreparedId().resultSetMetadata.id; + ColumnDefinitions definitionsAfter = rows.getColumnDefinitions(); + assertThat(idBefore).isNotEqualTo(idAfter); + assertThat(definitionsAfter) + .hasSize(4) + .containsVariable("d", DataType.cint()); + } + + @Test(groups = "short") + public void should_update_statement_id_when_metadata_changed_across_sessions() { + Session session1 = cluster().connect(); + useKeyspace(session1, keyspace); + Session session2 = cluster().connect(); + useKeyspace(session2, keyspace); + + PreparedStatement ps1 = session1.prepare("SELECT * FROM prepared_statement_invalidation_test WHERE a = ?"); + PreparedStatement ps2 = session2.prepare("SELECT * FROM prepared_statement_invalidation_test WHERE a = ?"); + + MD5Digest id1a = ps1.getPreparedId().resultSetMetadata.id; + MD5Digest id2a = ps2.getPreparedId().resultSetMetadata.id; + + ResultSet rows1 = session1.execute(ps1.bind(1)); + ResultSet rows2 = session2.execute(ps2.bind(1)); + + assertThat(rows1.getColumnDefinitions()) + .hasSize(3) + .containsVariable("a", DataType.cint()) + .containsVariable("b", DataType.cint()) + .containsVariable("c", DataType.cint()); + assertThat(rows2.getColumnDefinitions()) + .hasSize(3) + .containsVariable("a", DataType.cint()) + .containsVariable("b", DataType.cint()) + .containsVariable("c", DataType.cint()); + + session1.execute("ALTER TABLE prepared_statement_invalidation_test ADD d int"); + + rows1 = session1.execute(ps1.bind(1)); + rows2 = session2.execute(ps2.bind(1)); + + MD5Digest id1b = ps1.getPreparedId().resultSetMetadata.id; + MD5Digest id2b = ps2.getPreparedId().resultSetMetadata.id; + + assertThat(id1a).isNotEqualTo(id1b); + assertThat(id2a).isNotEqualTo(id2b); + + assertThat(ps1.getPreparedId().resultSetMetadata.variables) + .hasSize(4) + .containsVariable("d", DataType.cint()); + assertThat(ps2.getPreparedId().resultSetMetadata.variables) + .hasSize(4) + .containsVariable("d", DataType.cint()); + assertThat(rows1.getColumnDefinitions()) + .hasSize(4) + .containsVariable("d", DataType.cint()); + assertThat(rows2.getColumnDefinitions()) + .hasSize(4) + .containsVariable("d", DataType.cint()); + } + + @Test(groups = "short", expectedExceptions = NoHostAvailableException.class) + public void should_not_reprepare_invalid_statements() { + // given + session().execute("ALTER TABLE prepared_statement_invalidation_test ADD d int"); + PreparedStatement ps = session().prepare("SELECT a, b, c, d FROM prepared_statement_invalidation_test WHERE a = ?"); + session().execute("ALTER TABLE prepared_statement_invalidation_test DROP d"); + // when + session().execute(ps.bind()); + } + + @Test(groups = "short") + public void should_never_update_statement_id_for_conditional_updates_in_modern_protocol() { + should_never_update_statement_id_for_conditional_updates(session()); + } + + private void should_never_update_statement_id_for_conditional_updates(Session session) { + // Given + PreparedStatement ps = session.prepare( + "INSERT INTO prepared_statement_invalidation_test (a, b, c) VALUES (?, ?, ?) IF NOT EXISTS"); + + // Never store metadata in the prepared statement for conditional updates, since the result set can change + // depending on the outcome. + assertThat(ps.getPreparedId().resultSetMetadata.variables).isNull(); + MD5Digest idBefore = ps.getPreparedId().resultSetMetadata.id; + + // When + ResultSet rs = session.execute(ps.bind(5, 5, 5)); + + // Then + // Successful conditional update => only contains the [applied] column + assertThat(rs.wasApplied()).isTrue(); + assertThat(rs.getColumnDefinitions()) + .hasSize(1) + .containsVariable("[applied]", DataType.cboolean()); + // However the prepared statement shouldn't have changed + assertThat(ps.getPreparedId().resultSetMetadata.variables).isNull(); + assertThat(ps.getPreparedId().resultSetMetadata.id).isEqualTo(idBefore); + + + // When + rs = session.execute(ps.bind(5, 5, 5)); + + // Then + // Failed conditional update => regular metadata + assertThat(rs.wasApplied()).isFalse(); + assertThat(rs.getColumnDefinitions()).hasSize(4); + Row row = rs.one(); + assertThat(row.getBool("[applied]")).isFalse(); + assertThat(row.getInt("a")).isEqualTo(5); + assertThat(row.getInt("b")).isEqualTo(5); + assertThat(row.getInt("c")).isEqualTo(5); + // The prepared statement still shouldn't have changed + assertThat(ps.getPreparedId().resultSetMetadata.variables).isNull(); + assertThat(ps.getPreparedId().resultSetMetadata.id).isEqualTo(idBefore); + + + // When + session.execute("ALTER TABLE prepared_statement_invalidation_test ADD d int"); + rs = session.execute(ps.bind(5, 5, 5)); + + // Then + // Failed conditional update => regular metadata that should also contain the new column + assertThat(rs.wasApplied()).isFalse(); + assertThat(rs.getColumnDefinitions()).hasSize(5); + row = rs.one(); + assertThat(row.getBool("[applied]")).isFalse(); + assertThat(row.getInt("a")).isEqualTo(5); + assertThat(row.getInt("b")).isEqualTo(5); + assertThat(row.getInt("c")).isEqualTo(5); + assertThat(row.isNull("d")).isTrue(); + assertThat(ps.getPreparedId().resultSetMetadata.variables).isNull(); + assertThat(ps.getPreparedId().resultSetMetadata.id).isEqualTo(idBefore); + } + + @Test(groups = "short") + public void should_never_update_statement_for_conditional_updates_in_legacy_protocols() { + // Given + Cluster cluster = register(Cluster.builder() + .addContactPoints(getContactPoints()) + .withPort(ccm().getBinaryPort()) + .withProtocolVersion(ccm().getProtocolVersion(ProtocolVersion.V4)) + .build()); + Session session = cluster.connect(keyspace); + should_never_update_statement_id_for_conditional_updates(session); + } +} From 95b2039ba6c3e94bf418b525cf8e826fc83c62bf Mon Sep 17 00:00:00 2001 From: Joseph Lynch Date: Thu, 22 Jun 2017 19:52:42 -0700 Subject: [PATCH 031/382] JAVA-1670: Support user-provided JMX ports for CCMBridge This makes it possible to test multi node clusters and send the jmx commands to specific nodes for testing purposes (e.g. compaction, flushing, monitoring, repairs, etc ...) --- changelog/README.md | 1 + .../com/datastax/driver/core/CCMAccess.java | 10 +++ .../com/datastax/driver/core/CCMBridge.java | 40 ++++++++++-- .../datastax/driver/core/CCMBridgeTest.java | 65 +++++++++++++++++++ .../com/datastax/driver/core/CCMCache.java | 3 + .../datastax/driver/core/CCMTestsSupport.java | 3 + 6 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 driver-core/src/test/java/com/datastax/driver/core/CCMBridgeTest.java diff --git a/changelog/README.md b/changelog/README.md index 112c13942f3..880c856c804 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -4,6 +4,7 @@ - [bug] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names. - [improvement] JAVA-1196: Include hash of result set metadata in prepared statement id. +- [improvement] JAVA-1670: Support user-provided JMX ports for CCMBridge. ### 3.3.1 diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java index 04e6648255b..7a32c39ab12 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java @@ -101,6 +101,16 @@ enum Workload {cassandra, solr, hadoop, spark, cfs, graph} */ InetSocketAddress addressOfNode(int n); + /** + * Returns the address that the @{code nth} host in the CCM cluster is listening on JMX on (counting from 1, + * i.e, {@code jmxAddressOfNode(1)} returns the jmx address of the first node. + *

+ * In multi-DC setups, nodes are numbered in ascending order of their datacenter number. + * E.g. with 2 DCs and 3 nodes in each DC, the first node in DC 2 is number 4. + * + * @return the address of the JMX listener of the {@code nth} host in the cluster + */ + InetSocketAddress jmxAddressOfNode(int n); // Methods altering the whole cluster diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java index d79a8e8ae34..4181afd7cd2 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java @@ -286,8 +286,12 @@ public static boolean isWindows() { private final int[] nodes; - private CCMBridge(String clusterName, VersionNumber cassandraVersion, VersionNumber dseVersion, String ipPrefix, - int storagePort, int thriftPort, int binaryPort, String jvmArgs, int[] nodes) { + private final int[] jmxPorts; + + + protected CCMBridge(String clusterName, VersionNumber cassandraVersion, VersionNumber dseVersion, String ipPrefix, + int storagePort, int thriftPort, int binaryPort, int[] jmxPorts, String jvmArgs, int[] nodes) { + this.clusterName = clusterName; this.cassandraVersion = cassandraVersion; this.dseVersion = dseVersion; @@ -299,6 +303,7 @@ private CCMBridge(String clusterName, VersionNumber cassandraVersion, VersionNum this.jvmArgs = jvmArgs; this.nodes = nodes; this.ccmDir = Files.createTempDir(); + this.jmxPorts = jmxPorts; } public static Builder builder() { @@ -319,6 +324,11 @@ public InetSocketAddress addressOfNode(int n) { return new InetSocketAddress(ipOfNode(n), binaryPort); } + @Override + public InetSocketAddress jmxAddressOfNode(int n) { + return new InetSocketAddress("localhost", jmxPorts[n - 1]); + } + @Override public VersionNumber getCassandraVersion() { return cassandraVersion; @@ -789,6 +799,7 @@ public static class Builder { private String ipPrefix = TestUtils.IP_PREFIX; int[] nodes = {1}; + private int[] jmxPorts = {}; private boolean start = true; private boolean dse = false; private VersionNumber version = null; @@ -921,6 +932,11 @@ public Builder withBinaryPort(int port) { return this; } + public Builder withJmxPorts(int... ports) { + this.jmxPorts = ports; + return this; + } + /** * Sets the DSE workload for a given node. * @@ -959,13 +975,29 @@ public CCMBridge build() { int storagePort = Integer.parseInt(cassandraConfiguration.get("storage_port").toString()); int thriftPort = Integer.parseInt(cassandraConfiguration.get("rpc_port").toString()); int binaryPort = Integer.parseInt(cassandraConfiguration.get("native_transport_port").toString()); + + // Copy any supplied jmx ports over, and find available ports for the rest + int numNodes = 0; + for (int i : nodes) { + numNodes += i; + } + + int[] generatedJmxPorts = new int[numNodes]; + for (int i = 0; i < numNodes; i++) { + if (i >= jmxPorts.length) { + generatedJmxPorts[i] = TestUtils.findAvailablePort(); + } else { + generatedJmxPorts[i] = jmxPorts[i]; + } + } + if (!isThriftSupported(cassandraVersion)) { // remove thrift configuration cassandraConfiguration.remove("start_rpc"); cassandraConfiguration.remove("rpc_port"); cassandraConfiguration.remove("thrift_prepared_statements_cache_size_mb"); } - final CCMBridge ccm = new CCMBridge(clusterName, cassandraVersion, dseVersion, ipPrefix, storagePort, thriftPort, binaryPort, joinJvmArgs(), nodes); + final CCMBridge ccm = new CCMBridge(clusterName, cassandraVersion, dseVersion, ipPrefix, storagePort, thriftPort, binaryPort, generatedJmxPorts, joinJvmArgs(), nodes); Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -1068,7 +1100,7 @@ private void updateNodeConf(CCMBridge ccm) { for (int dc = 1; dc <= nodes.length; dc++) { int nodesInDc = nodes[dc - 1]; for (int i = 0; i < nodesInDc; i++) { - int jmxPort = TestUtils.findAvailablePort(); + int jmxPort = ccm.jmxAddressOfNode(n).getPort(); int debugPort = TestUtils.findAvailablePort(); logger.trace("Node {} in cluster {} using JMX port {} and debug port {}", n, ccm.getClusterName(), jmxPort, debugPort); File nodeConf = new File(ccm.getNodeDir(n), "node.conf"); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMBridgeTest.java b/driver-core/src/test/java/com/datastax/driver/core/CCMBridgeTest.java new file mode 100644 index 00000000000..2ab741e6ab5 --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMBridgeTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import org.testng.annotations.Test; + +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import java.net.InetSocketAddress; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * A simple test to validate jmx ports work + */ +@Test +@CCMConfig(numberOfNodes = 3) +public class CCMBridgeTest extends CCMTestsSupport { + + @Test(groups = "short") + public void should_make_JMX_connection() throws Exception { + InetSocketAddress addr1 = ccm().jmxAddressOfNode(1); + InetSocketAddress addr2 = ccm().jmxAddressOfNode(2); + InetSocketAddress addr3 = ccm().jmxAddressOfNode(3); + + assertThat(addr1.getPort()).isNotEqualTo(addr2.getPort()); + assertThat(addr1.getPort()).isNotEqualTo(addr3.getPort()); + assertThat(addr2.getPort()).isNotEqualTo(addr3.getPort()); + + JMXServiceURL url = new JMXServiceURL( + String.format( + "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", + addr2.getAddress().getHostAddress(), addr2.getPort() + ) + ); + JMXConnector jmxc = JMXConnectorFactory.connect(url, null); + assertThat(jmxc.getConnectionId().isEmpty()).isFalse(); + } + + @Test(groups = "short") + public void should_configure_JMX_ports_through_builder() throws Exception { + CCMBridge.Builder ccmBuilder = CCMBridge.builder().withNodes(3).notStarted().withJmxPorts(12345); + CCMAccess ccm = ccmBuilder.build(); + assertThat(ccm.jmxAddressOfNode(1).getPort()).isEqualTo(12345); + + int port2 = ccm.jmxAddressOfNode(2).getPort(); + int port3 = ccm.jmxAddressOfNode(3).getPort(); + assertThat(port2).isBetween(0, 65535); + assertThat(port3).isBetween(0, 65535); + } +} \ No newline at end of file diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java index 78eb8435202..9b83d462c13 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java @@ -103,6 +103,9 @@ public InetSocketAddress addressOfNode(int n) { return ccm.addressOfNode(n); } + @Override + public InetSocketAddress jmxAddressOfNode(int n) { return ccm.jmxAddressOfNode(n); } + @Override public void start() { ccm.start(); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java index 6046c0ce747..32903b1bb5b 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java @@ -92,6 +92,9 @@ public InetSocketAddress addressOfNode(int n) { return delegate.addressOfNode(n); } + @Override + public InetSocketAddress jmxAddressOfNode(int n) { return delegate.jmxAddressOfNode(n); } + @Override public File getCcmDir() { return delegate.getCcmDir(); From 5f42e52bb12907a8630f8289aada85c8301836f4 Mon Sep 17 00:00:00 2001 From: Dmitry Konstantinov Date: Mon, 30 Oct 2017 19:54:39 +0300 Subject: [PATCH 032/382] JAVA-1661: Avoid String.toLowerCase if possible in Metadata This method is invoked very frequently, minimize CPU usage and GC overheads. --- changelog/README.md | 1 + .../com/datastax/driver/core/Metadata.java | 107 +++++++++++++++--- .../datastax/driver/core/MetadataTest.java | 18 +++ 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 880c856c804..2da291725cf 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -5,6 +5,7 @@ - [bug] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names. - [improvement] JAVA-1196: Include hash of result set metadata in prepared statement id. - [improvement] JAVA-1670: Support user-provided JMX ports for CCMBridge. +- [improvement] JAVA-1661: Avoid String.toLowerCase if possible in Metadata. ### 3.3.1 diff --git a/driver-core/src/main/java/com/datastax/driver/core/Metadata.java b/driver-core/src/main/java/com/datastax/driver/core/Metadata.java index 1eddbb84ca0..bd172d8759d 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Metadata.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Metadata.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import io.netty.util.collection.IntObjectHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +46,7 @@ public class Metadata { final ReentrantLock lock = new ReentrantLock(); // See https://github.com/apache/cassandra/blob/trunk/doc/cql3/CQL.textile#appendixA - private static final Set RESERVED_KEYWORDS = ImmutableSet.of( + private static final IntObjectHashMap> RESERVED_KEYWORDS = indexByCaseInsensitiveHash( "add", "allow", "alter", "and", "any", "apply", "asc", "authorize", "batch", "begin", "by", "columnfamily", "create", "delete", "desc", "drop", "each_quorum", "from", "grant", "in", "index", "inet", "infinity", "insert", "into", "keyspace", "keyspaces", "limit", "local_one", @@ -125,25 +126,32 @@ static String handleId(String id) { if (id == null) return null; - if (isAlphanumeric(id)) - return id.toLowerCase(); - - // Check if it's enclosed in quotes. If it is, remove them and unescape internal double quotes - return ParseUtils.unDoubleQuote(id); - } - - private static boolean isAlphanumeric(String s) { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (!( + boolean isAlphanumericLowCase = true; + boolean isAlphanumeric = true; + for (int i = 0; i < id.length(); i++) { + char c = id.charAt(i); + if (c >= 65 && c <= 90) { // A-Z + isAlphanumericLowCase = false; + } else if (!( (c >= 48 && c <= 57) // 0-9 - || (c >= 65 && c <= 90) // A-Z || (c == 95) // _ (underscore) || (c >= 97 && c <= 122) // a-z - )) - return false; + )) { + isAlphanumeric = false; + isAlphanumericLowCase = false; + break; + } } - return true; + + if (isAlphanumericLowCase) { + return id; + } + if (isAlphanumeric) { + return id.toLowerCase(); + } + + // Check if it's enclosed in quotes. If it is, remove them and unescape internal double quotes + return ParseUtils.unDoubleQuote(id); } /** @@ -273,8 +281,73 @@ public static String quote(String id) { * @return {@code true} if the given identifier is a known reserved * CQL keyword, {@code false} otherwise. */ + public static boolean isReservedCqlKeyword(String id) { - return id != null && RESERVED_KEYWORDS.contains(id.toLowerCase()); + if (id == null) { + return false; + } + int hash = caseInsensitiveHash(id); + List keywords = RESERVED_KEYWORDS.get(hash); + if (keywords == null) { + return false; + } else { + for (char[] keyword : keywords) { + if (equalsIgnoreCaseAscii(id, keyword)) { + return true; + } + } + return false; + } + } + + private static int caseInsensitiveHash(String str) { + int hashCode = 17; + for (int i = 0; i < str.length(); i++) { + char c = toLowerCaseAscii(str.charAt(i)); + hashCode = 31 * hashCode + c; + } + return hashCode; + } + + // keyword is expected as a second argument always in low case + private static boolean equalsIgnoreCaseAscii(String str1, char[] str2LowCase) { + if (str1.length() != str2LowCase.length) return false; + + for (int i = 0; i < str1.length(); i++) { + char c1 = str1.charAt(i); + char c2Low = str2LowCase[i]; + if (c1 == c2Low) { + continue; + } + char low1 = toLowerCaseAscii(c1); + if (low1 == c2Low) { + continue; + } + return false; + } + return true; + } + + private static char toLowerCaseAscii(char c) { + if (c >= 65 && c <= 90) { // A-Z + c ^= 0x20; // convert to low case + } + return c; + } + + private static IntObjectHashMap> indexByCaseInsensitiveHash(String... words) { + IntObjectHashMap> result = new IntObjectHashMap>(); + for (String word : words) { + char[] wordAsCharArray = word.toLowerCase().toCharArray(); + int hash = caseInsensitiveHash(word); + List list = result.get(hash); + if (list == null) { + list = new ArrayList(); + result.put(hash, list); + } + list.add(wordAsCharArray); + } + return result; } /** diff --git a/driver-core/src/test/java/com/datastax/driver/core/MetadataTest.java b/driver-core/src/test/java/com/datastax/driver/core/MetadataTest.java index d101791c543..d28e6aeb7ba 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/MetadataTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/MetadataTest.java @@ -125,6 +125,7 @@ private Map getTokenForHosts(Metadata metadata) { public void handleId_should_lowercase_unquoted_alphanumeric_identifiers() { assertThat(Metadata.handleId("FooBar1")).isEqualTo("foobar1"); assertThat(Metadata.handleId("Foo_Bar_1")).isEqualTo("foo_bar_1"); + assertThat(Metadata.handleId("foo_bar_1")).isEqualTo("foo_bar_1"); } @Test(groups = "unit") @@ -161,4 +162,21 @@ public void escapeId_should_quote_reserved_cql_keywords() { assertThat(Metadata.quoteIfNecessary("columnfamily")).isEqualTo("\"columnfamily\""); } + @Test(groups = "unit") + public void should_detect_reserved_keywords_in_upper_case() { + assertThat(Metadata.isReservedCqlKeyword("COLUMNFAMILY")).isTrue(); + assertThat(Metadata.isReservedCqlKeyword("TEST_COLUMNFAMILY")).isFalse(); + } + + @Test(groups = "unit") + public void should_detect_reserved_keywords_in_lower_case() { + assertThat(Metadata.isReservedCqlKeyword("columnfamily")).isTrue(); + assertThat(Metadata.isReservedCqlKeyword("test_columnfamily")).isFalse(); + } + + @Test(groups = "unit") + public void should_detect_reserved_keywords_in_mixed_case() { + assertThat(Metadata.isReservedCqlKeyword("ColumnFamily")).isTrue(); + assertThat(Metadata.isReservedCqlKeyword("Test_ColumnFamily")).isFalse(); + } } From 83bfcad9bd3a1390ab91b4afa70402b687915307 Mon Sep 17 00:00:00 2001 From: Dmitry Konstantinov Date: Mon, 30 Oct 2017 17:50:15 +0300 Subject: [PATCH 033/382] JAVA-1659: Expose low-level flusher tuning options Introduce new tuning options: - com.datastax.driver.FLUSHER_SCHEDULE_PERIOD_NS - com.datastax.driver.FLUSHER_RUN_WITHOUT_WORK_TIMES Old behavior is kept as default. See also CASSANDRA-13651 for observations about the similar component on the server side. --- changelog/README.md | 1 + .../main/java/com/datastax/driver/core/Connection.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 2da291725cf..5c23244889f 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -6,6 +6,7 @@ - [improvement] JAVA-1196: Include hash of result set metadata in prepared statement id. - [improvement] JAVA-1670: Support user-provided JMX ports for CCMBridge. - [improvement] JAVA-1661: Avoid String.toLowerCase if possible in Metadata. +- [improvement] JAVA-1659: Expose low-level flusher tuning options. ### 3.3.1 diff --git a/driver-core/src/main/java/com/datastax/driver/core/Connection.java b/driver-core/src/main/java/com/datastax/driver/core/Connection.java index 73cff42a968..c46832854ec 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Connection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Connection.java @@ -66,6 +66,8 @@ class Connection { private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; private static final boolean DISABLE_COALESCING = SystemProperties.getBoolean("com.datastax.driver.DISABLE_COALESCING", false); + private static final int FLUSHER_SCHEDULE_PERIOD_NS = SystemProperties.getInt("com.datastax.driver.FLUSHER_SCHEDULE_PERIOD_NS", 10000); + private static final int FLUSHER_RUN_WITHOUT_WORK_TIMES = SystemProperties.getInt("com.datastax.driver.FLUSHER_RUN_WITHOUT_WORK_TIMES", 5); enum State {OPEN, TRASHED, RESURRECTING, GONE} @@ -953,7 +955,7 @@ public void run() { runsWithNoWork = 0; } else { // either reschedule or cancel - if (++runsWithNoWork > 5) { + if (++runsWithNoWork > FLUSHER_RUN_WITHOUT_WORK_TIMES) { running.set(false); if (queued.isEmpty() || !running.compareAndSet(false, true)) return; @@ -962,7 +964,11 @@ public void run() { EventLoop eventLoop = eventLoopRef.get(); if (eventLoop != null && !eventLoop.isShuttingDown()) { - eventLoop.schedule(this, 10000, TimeUnit.NANOSECONDS); + if (FLUSHER_SCHEDULE_PERIOD_NS > 0) { + eventLoop.schedule(this, FLUSHER_SCHEDULE_PERIOD_NS, TimeUnit.NANOSECONDS); + } else { + eventLoop.execute(this); + } } } } From f5d0e7e79854c04c4ed67cbd479fc544fc53eea6 Mon Sep 17 00:00:00 2001 From: Dmitry Konstantinov Date: Mon, 30 Oct 2017 18:31:37 +0300 Subject: [PATCH 034/382] JAVA-1660: Support netty-transport-native-epoll in OSGi container --- changelog/README.md | 1 + driver-core/pom.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog/README.md b/changelog/README.md index 5c23244889f..044e967b577 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -7,6 +7,7 @@ - [improvement] JAVA-1670: Support user-provided JMX ports for CCMBridge. - [improvement] JAVA-1661: Avoid String.toLowerCase if possible in Metadata. - [improvement] JAVA-1659: Expose low-level flusher tuning options. +- [improvement] JAVA-1660: Support netty-transport-native-epoll in OSGi container. ### 3.3.1 diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 2d0034acebb..3434673f955 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -228,7 +228,7 @@ ${project.build.outputDirectory}/META-INF - + From ea1f57fffde5bcb4e9579005984ee499ff889c03 Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 09:10:50 -0800 Subject: [PATCH 035/382] Fix failing test --- .../com/datastax/driver/core/ExportAsStringTest.java | 12 ++++++++---- pom.xml | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java index 2576f18b8fa..10ea7473331 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/ExportAsStringTest.java @@ -20,14 +20,15 @@ import com.google.common.collect.ImmutableMap; import com.google.common.io.ByteStreams; import com.google.common.io.Closer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; @@ -51,7 +52,7 @@ public class ExportAsStringTest extends CCMTestsSupport { * is failed. */ @Test(groups = "short") - public void create_schema_and_ensure_exported_cql_is_as_expected() { + public void should_create_schema_and_ensure_exported_cql_is_as_expected() { String keyspace = "complex_ks"; Map replicationOptions = ImmutableMap.of("class", "SimpleStrategy", "replication_factor", 1); @@ -204,6 +205,9 @@ private String getExpectedCqlString() { Closer closer = Closer.create(); try { InputStream is = ExportAsStringTest.class.getResourceAsStream(resourceName); + assertThat(is) + .as("No reference script for this version (was looking for src/test/resources" + resourceName + ")") + .isNotNull(); closer.register(is); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); diff --git a/pom.xml b/pom.xml index 57a9eb8811a..7d665b4c15c 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ UTF-8 UTF-8 - 3.10 + 3.11.1 1.6 1.2.17 1.7.25 From 6fcbc316be90aefffb8f59bd8aa689747fff66ce Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:32:48 -0800 Subject: [PATCH 036/382] [maven-release-plugin] prepare release 3.3.2 --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 3434673f955..1b247045e40 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index e50c6ff6400..5d0456c80e7 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 780f512bd14..2694b4791ee 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 3f2607f21ee..64c4947830d 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 68ce7bd2b99..9f5255b43ef 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index bb066034f77..fb2dd6e2128 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 6a83dbac0bb..71ad04e05b4 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 14df05792c5..85efa65108a 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index 277ef8a6f55..dd0cdc33826 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index c2e2e95a1f8..4b3daa5f88e 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 26c16dc2f5b..7ce9889d5ec 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index 7d665b4c15c..fce6ac14863 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - HEAD + 3.3.2 From 160d2a0d841c197ef353d5bc74ea6d737052518f Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:32:58 -0800 Subject: [PATCH 037/382] [maven-release-plugin] prepare for next development iteration --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 1b247045e40..3c48ee204af 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index 5d0456c80e7..2fd4eef3fba 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 2694b4791ee..b2b9e1fa617 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 64c4947830d..ce0b3fdeadb 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 9f5255b43ef..c8616e7448a 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index fb2dd6e2128..15ef3884c59 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 71ad04e05b4..0741b144651 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 85efa65108a..46b9f0fd971 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index dd0cdc33826..86f7de1392c 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index 4b3daa5f88e..efc5fd08d7d 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 7ce9889d5ec..ccc4c0b2589 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index fce6ac14863..1a3e60b4eee 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - 3.3.2 + HEAD From 1a0066f6e765e98faebf397955d2f168abda6938 Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:37:48 -0800 Subject: [PATCH 038/382] Revert release attempt --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 3c48ee204af..3434673f955 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index 2fd4eef3fba..e50c6ff6400 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index b2b9e1fa617..780f512bd14 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index ce0b3fdeadb..3f2607f21ee 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index c8616e7448a..68ce7bd2b99 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index 15ef3884c59..bb066034f77 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 0741b144651..6a83dbac0bb 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 46b9f0fd971..14df05792c5 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index 86f7de1392c..277ef8a6f55 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index efc5fd08d7d..c2e2e95a1f8 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index ccc4c0b2589..26c16dc2f5b 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index 1a3e60b4eee..7d665b4c15c 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.3-SNAPSHOT + 3.3.2-SNAPSHOT pom DataStax Java Driver for Apache Cassandra From ae618a5f90c3e4af9d7e3da46dadff0e14ef85c4 Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:43:19 -0800 Subject: [PATCH 039/382] Update version in docs --- README.md | 14 +++++++------- changelog/README.md | 2 +- faq/README.md | 2 +- manual/compression/README.md | 2 +- manual/custom_codecs/extras/README.md | 2 +- manual/object_mapper/README.md | 2 +- manual/shaded_jar/README.md | 6 +++--- pom.xml | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index db302c4e2f6..dc743ec43b1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ not yet have been released. You can find the documentation for latest version through [Java driver docs](http://datastax.github.io/java-driver/) or via the release tags, [e.g. -3.3.1](https://github.com/datastax/java-driver/tree/3.3.1).* +3.3.2](https://github.com/datastax/java-driver/tree/3.3.2).* A modern, [feature-rich](manual/) and highly tunable Java client library for Apache Cassandra (1.2+) and DataStax Enterprise (3.1+) using @@ -55,7 +55,7 @@ The driver contains the following modules: start material and technical details about the driver and its features. - API: http://www.datastax.com/drivers/java/3.2 - [changelog](changelog/) -- [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.1.tar.gz) +- [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.2.tar.gz) **Feeback requested:** help us focus our efforts, provide your input on the [Platform and Runtime Survey](http://goo.gl/forms/qwUE6qnL7U) (we kept it short). @@ -68,7 +68,7 @@ it in your application using the following Maven dependency: com.datastax.cassandra cassandra-driver-core - 3.3.1 + 3.3.2 ``` @@ -78,7 +78,7 @@ Note that the object mapper is published as a separate artifact: com.datastax.cassandra cassandra-driver-mapping - 3.3.1 + 3.3.2 ``` @@ -88,7 +88,7 @@ The 'extras' module is also published as a separate artifact: com.datastax.cassandra cassandra-driver-extras - 3.3.1 + 3.3.2 ``` @@ -97,12 +97,12 @@ We also provide a [shaded JAR](manual/shaded_jar/) to avoid the explicit dependency to Netty. If you can't use a dependency management tool, a -[binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.1.tar.gz) +[binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.2.tar.gz) is available for download. ## Compatibility -The Java client driver 3.3.1 ([branch 3.x](https://github.com/datastax/java-driver/tree/3.x)) is compatible with Apache +The Java client driver 3.3.2 ([branch 3.x](https://github.com/datastax/java-driver/tree/3.x)) is compatible with Apache Cassandra 1.2, 2.0, 2.1, 2.2 and 3.0 (see [this page](http://datastax.github.io/java-driver/manual/native_protocol) for the most up-to-date compatibility information). diff --git a/changelog/README.md b/changelog/README.md index 044e967b577..a97d6d08b25 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,6 +1,6 @@ ## Changelog -### 3.3.2 (in progress) +### 3.3.2 - [bug] JAVA-1666: Fix keyspace export when a UDT has case-sensitive field names. - [improvement] JAVA-1196: Include hash of result set metadata in prepared statement id. diff --git a/faq/README.md b/faq/README.md index d902570f6bf..b9adb5c79eb 100644 --- a/faq/README.md +++ b/faq/README.md @@ -258,7 +258,7 @@ If properly used, the following log message will be logged at INFO on startup: > Found Netty's native epoll transport in the classpath, but NIO was forced through the FORCE_NIO system property. -[Blobs.java]: https://github.com/datastax/java-driver/tree/3.3.1/driver-examples/src/main/java/com/datastax/driver/examples/datatypes/Blobs.java +[Blobs.java]: https://github.com/datastax/java-driver/tree/3.3.2/driver-examples/src/main/java/com/datastax/driver/examples/datatypes/Blobs.java [CASSANDRA-7304]: https://issues.apache.org/jira/browse/CASSANDRA-7304 [Parameters and Binding]: ../manual/statements/prepared/#parameters-and-binding [Mapper options]: ../manual/object_mapper/using/#mapper-options diff --git a/manual/compression/README.md b/manual/compression/README.md index 7bbb89aedbe..541777b209a 100644 --- a/manual/compression/README.md +++ b/manual/compression/README.md @@ -85,4 +85,4 @@ cluster = Cluster.builder() .build(); ``` -[pom]: https://repo1.maven.org/maven2/com/datastax/cassandra/cassandra-driver-parent/3.3.1/cassandra-driver-parent-3.3.1.pom +[pom]: https://repo1.maven.org/maven2/com/datastax/cassandra/cassandra-driver-parent/3.3.2/cassandra-driver-parent-3.3.2.pom diff --git a/manual/custom_codecs/extras/README.md b/manual/custom_codecs/extras/README.md index 9a30f888380..09cd8f85dbd 100644 --- a/manual/custom_codecs/extras/README.md +++ b/manual/custom_codecs/extras/README.md @@ -10,7 +10,7 @@ The module is published as a separate Maven artifact: com.datastax.cassandra cassandra-driver-extras - 3.3.1 + 3.3.2 ``` diff --git a/manual/object_mapper/README.md b/manual/object_mapper/README.md index cc8f6901de7..f4a9f92744c 100644 --- a/manual/object_mapper/README.md +++ b/manual/object_mapper/README.md @@ -11,7 +11,7 @@ The mapper is published as a separate Maven artifact: com.datastax.cassandra cassandra-driver-mapping - 3.3.1 + 3.3.2 ``` diff --git a/manual/shaded_jar/README.md b/manual/shaded_jar/README.md index 7a49f2bcb85..1973ab7e7a0 100644 --- a/manual/shaded_jar/README.md +++ b/manual/shaded_jar/README.md @@ -12,7 +12,7 @@ package name: com.datastax.cassandra cassandra-driver-core - 3.3.1 + 3.3.2 shaded @@ -32,7 +32,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-core - 3.3.1 + 3.3.2 shaded @@ -44,7 +44,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-mapping - 3.3.1 + 3.3.2 com.datastax.cassandra diff --git a/pom.xml b/pom.xml index 7d665b4c15c..2b4ed25f412 100644 --- a/pom.xml +++ b/pom.xml @@ -631,7 +631,7 @@ - 3.3.0 + 3.3.1 ../clirr-ignores.xml com/datastax/shaded/** From 7548daedcd5795062f8cd09ea9c059acb7b5ef66 Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:44:55 -0800 Subject: [PATCH 040/382] [maven-release-plugin] prepare release 3.3.2 --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 3434673f955..1b247045e40 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index e50c6ff6400..5d0456c80e7 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 780f512bd14..2694b4791ee 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 3f2607f21ee..64c4947830d 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 68ce7bd2b99..9f5255b43ef 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index bb066034f77..fb2dd6e2128 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 6a83dbac0bb..71ad04e05b4 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 14df05792c5..85efa65108a 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index 277ef8a6f55..dd0cdc33826 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index c2e2e95a1f8..4b3daa5f88e 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 26c16dc2f5b..7ce9889d5ec 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2-SNAPSHOT + 3.3.2 cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index 2b4ed25f412..da648356ec5 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2-SNAPSHOT + 3.3.2 pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - HEAD + 3.3.2 From c723d5ecd7f0b0faedd180f5dc3fd492353bbfb9 Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 20 Nov 2017 10:45:05 -0800 Subject: [PATCH 041/382] [maven-release-plugin] prepare for next development iteration --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 1b247045e40..3c48ee204af 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index 5d0456c80e7..2fd4eef3fba 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 2694b4791ee..b2b9e1fa617 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 64c4947830d..ce0b3fdeadb 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 9f5255b43ef..c8616e7448a 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index fb2dd6e2128..15ef3884c59 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 71ad04e05b4..0741b144651 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 85efa65108a..46b9f0fd971 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index dd0cdc33826..86f7de1392c 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index 4b3daa5f88e..efc5fd08d7d 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index 7ce9889d5ec..ccc4c0b2589 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.3.2 + 3.3.3-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index da648356ec5..585a105ec63 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.3.2 + 3.3.3-SNAPSHOT pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - 3.3.2 + HEAD From f21fa6f3a08fa0b4dbe6a42a03d322ce1d194573 Mon Sep 17 00:00:00 2001 From: marcogalluzzi Date: Tue, 28 Nov 2017 15:03:25 +0000 Subject: [PATCH 042/382] Update Manual and API links version Both Manual and API links point at version 3.2. I've changed to the correct 3.3 version. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 25b0d4754d7..f580628fdf8 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,9 @@ The driver contains the following modules: driver releases and important announcements (low frequency). [@DataStaxEng](https://twitter.com/datastaxeng) has more news including other drivers, Cassandra, and DSE. -- DOCS: the [manual](http://docs.datastax.com/en/developer/java-driver/3.2/manual/) has quick +- DOCS: the [manual](http://docs.datastax.com/en/developer/java-driver/3.3/manual/) has quick start material and technical details about the driver and its features. -- API: http://www.datastax.com/drivers/java/3.2 +- API: http://www.datastax.com/drivers/java/3.3 - [changelog](changelog/) - [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.0.tar.gz) From 2dcdbf106643a9d2ca41a7c134f4f9dc93b605b3 Mon Sep 17 00:00:00 2001 From: marcogalluzzi Date: Tue, 28 Nov 2017 15:03:25 +0000 Subject: [PATCH 043/382] Update Manual and API links version Both Manual and API links point at version 3.2. I've changed to the correct 3.3 version. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc743ec43b1..69ad033b41d 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,9 @@ The driver contains the following modules: driver releases and important announcements (low frequency). [@DataStaxEng](https://twitter.com/datastaxeng) has more news including other drivers, Cassandra, and DSE. -- DOCS: the [manual](http://docs.datastax.com/en/developer/java-driver/3.2/manual/) has quick +- DOCS: the [manual](http://docs.datastax.com/en/developer/java-driver/3.3/manual/) has quick start material and technical details about the driver and its features. -- API: http://www.datastax.com/drivers/java/3.2 +- API: http://www.datastax.com/drivers/java/3.3 - [changelog](changelog/) - [binary tarball](http://downloads.datastax.com/java-driver/cassandra-java-driver-3.3.2.tar.gz) From 46e6b11a96829330bcd5a0cd80287f687f2c7ea0 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 8 Dec 2017 16:30:52 -0600 Subject: [PATCH 044/382] JAVA-1671: Remove unnecessary test on prepared statement metadata As CASSANDRA-13992 is fixed this test is no longer needed. --- changelog/README.md | 2 ++ .../datastax/driver/core/ArrayBackedResultSet.java | 11 +---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 9ec1129ed00..3fd53ac6cfe 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -2,6 +2,8 @@ ### 3.4.0 (In progress) +- [improvement] JAVA-1671: Remove unnecessary test on prepared statement metadata. + Merged from 3.3.x: - [bug] JAVA-1555: Include VIEW and CDC in WriteType. diff --git a/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java b/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java index 81e348afb4c..f14ad91256b 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ArrayBackedResultSet.java @@ -83,16 +83,7 @@ static ArrayBackedResultSet fromMessage(Responses.Result msg, SessionManager ses if (newMetadataId != null) { BoundStatement bs = ((BoundStatement) actualStatement); PreparedId preparedId = bs.preparedStatement().getPreparedId(); - // Extra test for CASSANDRA-13992: conditional updates yield a different result set depending on - // whether the update was applied or not, so the prepared statement must never have result - // metadata, and we should always execute with skip_metadata = false. - // However the server sends a new_metadata_id in the response, so make sure we ignore it if the - // prepared statement did not have metadata in the first place. - // TODO remove the "if" (i.e. always assign resultSetMetadata) if CASSANDRA-13992 gets fixed before 4.0.0 GA - if (preparedId.resultSetMetadata.variables != null) { - preparedId.resultSetMetadata = - new PreparedId.PreparedMetadata(newMetadataId, columnDefs); - } + preparedId.resultSetMetadata = new PreparedId.PreparedMetadata(newMetadataId, columnDefs); } } assert columnDefs != null; From 1f57d1feefda4d7a247912a924869469223be2df Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Thu, 21 Dec 2017 13:10:31 -0600 Subject: [PATCH 045/382] JAVA-1694: Upgrade to jackson-databind 2.7.9.2 to address CVE-2015-15095 --- changelog/README.md | 1 + pom.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog/README.md b/changelog/README.md index 3fd53ac6cfe..4244d99fb68 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -3,6 +3,7 @@ ### 3.4.0 (In progress) - [improvement] JAVA-1671: Remove unnecessary test on prepared statement metadata. +- [bug] JAVA-1694: Upgrade to jackson-databind 2.7.9.2 to address CVE-2015-15095. Merged from 3.3.x: diff --git a/pom.xml b/pom.xml index 3b3379f7369..6aa6e30132b 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 2.1.9 2.8.8 - 2.7.9.1 + 2.7.9.2 2.9.1 1.0 1.0.4 From abed4c2e03477a2716a1c674aa2aa9bc2ab5bd13 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 2 Jan 2018 09:41:52 -0800 Subject: [PATCH 046/382] JAVA-1685: Clarify recommendation on preparing SELECT * --- changelog/README.md | 1 + manual/statements/prepared/README.md | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 4244d99fb68..71777e11d87 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -4,6 +4,7 @@ - [improvement] JAVA-1671: Remove unnecessary test on prepared statement metadata. - [bug] JAVA-1694: Upgrade to jackson-databind 2.7.9.2 to address CVE-2015-15095. +- [documentation] JAVA-1685: Clarify recommendation on preparing SELECT *. Merged from 3.3.x: diff --git a/manual/statements/prepared/README.md b/manual/statements/prepared/README.md index 2132db700ae..e6d351d07a8 100644 --- a/manual/statements/prepared/README.md +++ b/manual/statements/prepared/README.md @@ -249,10 +249,9 @@ is currently no mechanism for Cassandra to invalidate the existing metadata. Be the driver is not able to properly react to these changes and will improperly read rows after a schema change is made. -Therefore it is currently recommended to not create prepared statements -for 'SELECT *' queries if you plan on making schema changes involving -adding or dropping columns. Alternatively you should list all columns of interest -in your statement, i.e.: `SELECT a, b, c FROM tbl`. +Therefore it is currently recommended to list all columns of interest in +your prepared statements (i.e. `SELECT a, b, c FROM table`), instead of +relying on `SELECT *`. This will be addressed in a future release of both Cassandra and the driver. Follow [CASSANDRA-10786] and [JAVA-1196] for more information. @@ -264,4 +263,4 @@ This will be addressed in a future release of both Cassandra and the driver. Fo [execute]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- [executeAsync]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- [CASSANDRA-10786]: https://issues.apache.org/jira/browse/CASSANDRA-10786 -[JAVA-1196]: https://datastax-oss.atlassian.net/browse/JAVA-1196 \ No newline at end of file +[JAVA-1196]: https://datastax-oss.atlassian.net/browse/JAVA-1196 From 2fef368c578f4d4a365486883b3db6cda50ff4df Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 2 Jan 2018 10:01:29 -0800 Subject: [PATCH 047/382] JAVA-1679: Improve error message on batch log write timeout --- changelog/README.md | 1 + .../driver/core/exceptions/WriteTimeoutException.java | 4 +++- .../driver/core/exceptions/ExceptionsScassandraTest.java | 2 +- .../com/datastax/driver/core/exceptions/ExceptionsTest.java | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 71777e11d87..b312f54918d 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -5,6 +5,7 @@ - [improvement] JAVA-1671: Remove unnecessary test on prepared statement metadata. - [bug] JAVA-1694: Upgrade to jackson-databind 2.7.9.2 to address CVE-2015-15095. - [documentation] JAVA-1685: Clarify recommendation on preparing SELECT *. +- [improvement] JAVA-1679: Improve error message on batch log write timeout. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/exceptions/WriteTimeoutException.java b/driver-core/src/main/java/com/datastax/driver/core/exceptions/WriteTimeoutException.java index df0c80916cc..21b5779ec64 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/exceptions/WriteTimeoutException.java +++ b/driver-core/src/main/java/com/datastax/driver/core/exceptions/WriteTimeoutException.java @@ -40,7 +40,9 @@ public WriteTimeoutException(ConsistencyLevel consistency, WriteType writeType, public WriteTimeoutException(InetSocketAddress address, ConsistencyLevel consistency, WriteType writeType, int received, int required) { super( address, - String.format("Cassandra timeout during write query at consistency %s (%d replica were required but only %d acknowledged the write)", consistency, required, received), + String.format("Cassandra timeout during %s write query at consistency %s " + + "(%d replica were required but only %d acknowledged the write)", + writeType, consistency, required, received), consistency, received, required); diff --git a/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsScassandraTest.java b/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsScassandraTest.java index daa3347f234..3e37ee9afd7 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsScassandraTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsScassandraTest.java @@ -103,7 +103,7 @@ public void should_throw_proper_write_timeout_exception() { query(); fail("expected a WriteTimeoutException"); } catch (WriteTimeoutException e) { - assertThat(e.getMessage()).isEqualTo("Cassandra timeout during write query at consistency LOCAL_ONE (1 replica were required but only 0 acknowledged the write)"); + assertThat(e.getMessage()).isEqualTo("Cassandra timeout during SIMPLE write query at consistency LOCAL_ONE (1 replica were required but only 0 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_ONE); assertThat(e.getReceivedAcknowledgements()).isEqualTo(0); assertThat(e.getRequiredAcknowledgements()).isEqualTo(1); diff --git a/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsTest.java b/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsTest.java index d5b18085e5a..d3116804246 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/exceptions/ExceptionsTest.java @@ -304,7 +304,7 @@ public void should_create_proper_read_timeout_exception() { @Test(groups = "unit") public void should_create_proper_write_timeout_exception() { WriteTimeoutException e = new WriteTimeoutException(address1, LOCAL_QUORUM, WriteType.BATCH, 2, 3); - assertThat(e.getMessage()).isEqualTo("Cassandra timeout during write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); + assertThat(e.getMessage()).isEqualTo("Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); @@ -312,7 +312,7 @@ public void should_create_proper_write_timeout_exception() { assertThat(e.getAddress()).isEqualTo(address1); assertThat(e.getHost()).isEqualTo(address1.getAddress()); e = e.copy(address2); - assertThat(e.getMessage()).isEqualTo("Cassandra timeout during write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); + assertThat(e.getMessage()).isEqualTo("Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); From 993838ca5681f82e83b8d230a80c9038cd6f3a30 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 2 Jan 2018 11:06:07 -0800 Subject: [PATCH 048/382] JAVA-1672: Remove schema agreement check when repreparing on up --- changelog/README.md | 1 + .../src/main/java/com/datastax/driver/core/Cluster.java | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index b312f54918d..7ee216070ac 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -6,6 +6,7 @@ - [bug] JAVA-1694: Upgrade to jackson-databind 2.7.9.2 to address CVE-2015-15095. - [documentation] JAVA-1685: Clarify recommendation on preparing SELECT *. - [improvement] JAVA-1679: Improve error message on batch log write timeout. +- [improvement] JAVA-1672: Remove schema agreement check when repreparing on up. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java index 145100f0ccb..5e514a86c5c 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java @@ -2249,12 +2249,6 @@ private Connection prepareAllQueries(Host host, Connection reusedConnection) thr ? connectionFactory.open(host) : reusedConnection; - try { - ControlConnection.waitForSchemaAgreement(connection, this); - } catch (ExecutionException e) { - // As below, just move on - } - // Furthermore, along with each prepared query we keep the current keyspace at the time of preparation // as we need to make it is the same when we re-prepare on new/restarted nodes. Most query will use the // same keyspace so keeping it each time is slightly wasteful, but this doesn't really matter and is From d437684370001f3a6c8c9e420de8baffa3a20433 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 2 Jan 2018 10:47:19 -0800 Subject: [PATCH 049/382] JAVA-1677: Warn if auth is configured on the client but not the server --- changelog/README.md | 1 + .../com/datastax/driver/core/Connection.java | 6 +++ .../driver/core/NoAuthenticationTest.java | 46 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 driver-core/src/test/java/com/datastax/driver/core/NoAuthenticationTest.java diff --git a/changelog/README.md b/changelog/README.md index 7ee216070ac..bc58e4c16c9 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -7,6 +7,7 @@ - [documentation] JAVA-1685: Clarify recommendation on preparing SELECT *. - [improvement] JAVA-1679: Improve error message on batch log write timeout. - [improvement] JAVA-1672: Remove schema agreement check when repreparing on up. +- [improvement] JAVA-1677: Warn if auth is configured on the client but not the server. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/Connection.java b/driver-core/src/main/java/com/datastax/driver/core/Connection.java index c46832854ec..d33a1093319 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Connection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Connection.java @@ -246,6 +246,12 @@ private AsyncFunction onStartupResponse(final ProtocolVe public ListenableFuture apply(Message.Response response) throws Exception { switch (response.type) { case READY: + if (factory.authProvider != AuthProvider.NONE) { + logger.warn("{} did not send an authentication challenge; " + + "This is suspicious because the driver expects authentication " + + "(configured auth provider = {})", + address, factory.authProvider.getClass().getName()); + } return checkClusterName(protocolVersion, initExecutor); case ERROR: Responses.Error error = (Responses.Error) response; diff --git a/driver-core/src/test/java/com/datastax/driver/core/NoAuthenticationTest.java b/driver-core/src/test/java/com/datastax/driver/core/NoAuthenticationTest.java new file mode 100644 index 00000000000..973ba8e13af --- /dev/null +++ b/driver-core/src/test/java/com/datastax/driver/core/NoAuthenticationTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +import org.apache.log4j.Level; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +@CCMConfig(createCluster = false) +public class NoAuthenticationTest extends CCMTestsSupport { + + @Test(groups = "short") + public void should_warn_if_auth_configured_but_server_does_not_send_challenge() { + Cluster cluster = register(Cluster.builder() + .addContactPoints(getContactPoints()) + .withPort(ccm().getBinaryPort()) + .withCredentials("bogus", "bogus") + .build()); + Level previous = TestUtils.setLogLevel(Connection.class, Level.WARN); + MemoryAppender logs = new MemoryAppender().enableFor(Connection.class); + try { + cluster.init(); + } finally { + TestUtils.setLogLevel(Connection.class, previous); + logs.disableFor(Connection.class); + } + assertThat(logs.get()) + .contains("did not send an authentication challenge; " + + "This is suspicious because the driver expects authentication " + + "(configured auth provider = com.datastax.driver.core.PlainTextAuthProvider)"); + } +} From b4e444ec7a489f46e62ca02692fa062c65101bf4 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Fri, 8 Dec 2017 15:16:59 -0600 Subject: [PATCH 050/382] JAVA-1651: Add NO_COMPACT startup option --- changelog/README.md | 1 + .../com/datastax/driver/core/Cluster.java | 21 +++++++++++++- .../com/datastax/driver/core/Connection.java | 4 +-- .../datastax/driver/core/ProtocolOptions.java | 29 ++++++++++++++++++- .../com/datastax/driver/core/Requests.java | 9 ++++-- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index bc58e4c16c9..3e55b6701c0 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -8,6 +8,7 @@ - [improvement] JAVA-1679: Improve error message on batch log write timeout. - [improvement] JAVA-1672: Remove schema agreement check when repreparing on up. - [improvement] JAVA-1677: Warn if auth is configured on the client but not the server. +- [new feature] JAVA-1651: Add NO_COMPACT startup option. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java index 5e514a86c5c..726314e9fa7 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java @@ -687,6 +687,7 @@ public static class Builder implements Initializer { private boolean metricsEnabled = true; private boolean jmxEnabled = true; private boolean allowBetaProtocolVersion = false; + private boolean noCompact = false; private Collection listeners; @@ -1295,6 +1296,24 @@ public Builder withNettyOptions(NettyOptions nettyOptions) { return this; } + /** + * Enables the NO_COMPACT startup option. + *

+ * When this option is supplied, SELECT, UPDATE, DELETE and + * BATCH statements on COMPACT STORAGE tables function in "compatibility" mode which + * allows seeing these tables as if they were "regular" CQL tables. + *

+ * This option only effects interactions with tables using COMPACT STORAGE and is only supported by + * C* 4.0+ and DSE 6.0+. + * + * @return this builder. + * @see CASSANDRA-10857 + */ + public Builder withNoCompact() { + this.noCompact = true; + return this; + } + /** * The configuration that will be used for the new cluster. *

@@ -1306,7 +1325,7 @@ public Builder withNettyOptions(NettyOptions nettyOptions) { */ @Override public Configuration getConfiguration() { - ProtocolOptions protocolOptions = new ProtocolOptions(port, protocolVersion, maxSchemaAgreementWaitSeconds, sslOptions, authProvider) + ProtocolOptions protocolOptions = new ProtocolOptions(port, protocolVersion, maxSchemaAgreementWaitSeconds, sslOptions, authProvider, noCompact) .setCompression(compression); MetricsOptions metricsOptions = new MetricsOptions(metricsEnabled, jmxEnabled); diff --git a/driver-core/src/main/java/com/datastax/driver/core/Connection.java b/driver-core/src/main/java/com/datastax/driver/core/Connection.java index d33a1093319..9dd3e8d16ae 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Connection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Connection.java @@ -232,8 +232,8 @@ private AsyncFunction onChannelReady(final ProtocolVersion protocolV return new AsyncFunction() { @Override public ListenableFuture apply(Void input) throws Exception { - ProtocolOptions.Compression compression = factory.configuration.getProtocolOptions().getCompression(); - Future startupResponseFuture = write(new Requests.Startup(compression)); + ProtocolOptions protocolOptions = factory.configuration.getProtocolOptions(); + Future startupResponseFuture = write(new Requests.Startup(protocolOptions.getCompression(), protocolOptions.isNoCompact())); return GuavaCompatibility.INSTANCE.transformAsync(startupResponseFuture, onStartupResponse(protocolVersion, initExecutor), initExecutor); } diff --git a/driver-core/src/main/java/com/datastax/driver/core/ProtocolOptions.java b/driver-core/src/main/java/com/datastax/driver/core/ProtocolOptions.java index 77848c0fc99..ae2841b8df7 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ProtocolOptions.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ProtocolOptions.java @@ -99,6 +99,8 @@ public String toString() { private final SSLOptions sslOptions; // null if no SSL private final AuthProvider authProvider; + private final boolean noCompact; + private volatile Compression compression = Compression.NONE; /** @@ -118,7 +120,7 @@ public ProtocolOptions() { * @param port the port to use for the binary protocol. */ public ProtocolOptions(int port) { - this(port, null, DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS, null, AuthProvider.NONE); + this(port, null, DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS, null, AuthProvider.NONE, false); } /** @@ -135,11 +137,30 @@ public ProtocolOptions(int port) { * the Cassandra nodes. */ public ProtocolOptions(int port, ProtocolVersion protocolVersion, int maxSchemaAgreementWaitSeconds, SSLOptions sslOptions, AuthProvider authProvider) { + this(port, protocolVersion, maxSchemaAgreementWaitSeconds, sslOptions, authProvider, false); + } + + /** + * Creates a new {@code ProtocolOptions} instance using the provided port + * and SSL context. + * + * @param port the port to use for the binary protocol. + * @param protocolVersion the protocol version to use. This can be {@code null}, in which case the + * version used will be the biggest version supported by the first node the driver connects to. + * See {@link Cluster.Builder#withProtocolVersion} for more details. + * @param sslOptions the SSL options to use. Use {@code null} if SSL is not + * to be used. + * @param authProvider the {@code AuthProvider} to use for authentication against + * the Cassandra nodes. + * @param noCompact whether or not to include the NO_COMPACT startup option. + */ + public ProtocolOptions(int port, ProtocolVersion protocolVersion, int maxSchemaAgreementWaitSeconds, SSLOptions sslOptions, AuthProvider authProvider, boolean noCompact) { this.port = port; this.initialProtocolVersion = protocolVersion; this.maxSchemaAgreementWaitSeconds = maxSchemaAgreementWaitSeconds; this.sslOptions = sslOptions; this.authProvider = authProvider; + this.noCompact = noCompact; } void register(Cluster.Manager manager) { @@ -231,4 +252,10 @@ public AuthProvider getAuthProvider() { return authProvider; } + /** + * @return Whether or not to include the NO_COMPACT startup option. + */ + public boolean isNoCompact() { + return noCompact; + } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/Requests.java b/driver-core/src/main/java/com/datastax/driver/core/Requests.java index 3af73f4d9b8..163261761a3 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Requests.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Requests.java @@ -35,6 +35,7 @@ static class Startup extends Message.Request { private static final String CQL_VERSION = "3.0.0"; static final String COMPRESSION_OPTION = "COMPRESSION"; + static final String NO_COMPACT_OPTION = "NO_COMPACT"; static final Message.Coder coder = new Message.Coder() { @Override @@ -50,21 +51,25 @@ public int encodedSize(Startup msg, ProtocolVersion version) { private final Map options; private final ProtocolOptions.Compression compression; + private final boolean noCompact; - Startup(ProtocolOptions.Compression compression) { + Startup(ProtocolOptions.Compression compression, boolean noCompact) { super(Message.Request.Type.STARTUP); this.compression = compression; + this.noCompact = noCompact; ImmutableMap.Builder map = new ImmutableMap.Builder(); map.put(CQL_VERSION_OPTION, CQL_VERSION); if (compression != ProtocolOptions.Compression.NONE) map.put(COMPRESSION_OPTION, compression.toString()); + if (noCompact) + map.put(NO_COMPACT_OPTION, "true"); this.options = map.build(); } @Override protected Request copyInternal() { - return new Startup(compression); + return new Startup(compression, noCompact); } @Override From 922d614dfd54599698a291620aca6409b870e665 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Thu, 4 Jan 2018 11:01:32 -0500 Subject: [PATCH 051/382] Add note to README about JDK 6 support --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f580628fdf8..a72e8c3e3c1 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,8 @@ Other features are available only when using Apache Cassandra 2.0 or higher (e.g Trying to use these with a cluster running Cassandra 1.2 will result in an [UnsupportedFeatureException](https://github.com/datastax/java-driver/blob/3.x/driver-core/src/main/java/com/datastax/driver/core/exceptions/UnsupportedFeatureException.java) being thrown. +The java driver supports Java JDK versions 6 and above. + __Note__: DataStax products do not support big-endian systems. ## Upgrading from previous versions From 93172fb236e3a91bb81183d9efd9e7e57020466c Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 2 Jan 2018 14:14:59 -0800 Subject: [PATCH 052/382] JAVA-1683: Add metrics to track writes to nodes --- changelog/README.md | 1 + .../com/datastax/driver/core/MetricsUtil.java | 33 +++++++++++++++++++ .../datastax/driver/core/RequestHandler.java | 18 +++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 driver-core/src/main/java/com/datastax/driver/core/MetricsUtil.java diff --git a/changelog/README.md b/changelog/README.md index 3e55b6701c0..6e13aae2618 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -9,6 +9,7 @@ - [improvement] JAVA-1672: Remove schema agreement check when repreparing on up. - [improvement] JAVA-1677: Warn if auth is configured on the client but not the server. - [new feature] JAVA-1651: Add NO_COMPACT startup option. +- [improvement] JAVA-1683: Add metrics to track writes to nodes. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/MetricsUtil.java b/driver-core/src/main/java/com/datastax/driver/core/MetricsUtil.java new file mode 100644 index 00000000000..f1a880df8d4 --- /dev/null +++ b/driver-core/src/main/java/com/datastax/driver/core/MetricsUtil.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +public class MetricsUtil { + + public static String hostMetricName(String prefix, Host host) { + StringBuilder result = new StringBuilder(prefix); + boolean first = true; + for (byte b : host.getSocketAddress().getAddress().getAddress()) { + if (first) { + first = false; + } else { + result.append('_'); + } + result.append(b & 0xFF); + } + return result.toString(); + } +} diff --git a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java index 49f0869fdf0..97a45f9d3dc 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java +++ b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java @@ -50,6 +50,8 @@ class RequestHandler { private static final Logger logger = LoggerFactory.getLogger(RequestHandler.class); + private static final boolean HOST_METRICS_ENABLED = Boolean.getBoolean("com.datastax.driver.HOST_METRICS_ENABLED"); + final String id; private final SessionManager manager; @@ -234,6 +236,10 @@ private boolean metricsEnabled() { return manager.configuration().getMetricsOptions().isEnabled(); } + private boolean hostMetricsEnabled() { + return HOST_METRICS_ENABLED && metricsEnabled(); + } + private Metrics metrics() { return manager.cluster.manager.metrics; } @@ -290,8 +296,18 @@ void findNextHostAndQuery() { try { Host host; while (!isDone.get() && (host = queryPlan.next()) != null && !queryStateRef.get().isCancelled()) { - if (query(host)) + if (query(host)) { + if (hostMetricsEnabled()) { + metrics().getRegistry() + .counter(MetricsUtil.hostMetricName("writes.", host)) + .inc(); + } return; + } else if (hostMetricsEnabled()) { + metrics().getRegistry() + .counter(MetricsUtil.hostMetricName("write-errors.", host)) + .inc(); + } } if (current != null) { if (triedHosts == null) From 58af03b7474fc25643b7531e6e2c3103fab17f16 Mon Sep 17 00:00:00 2001 From: olim7t Date: Tue, 9 Jan 2018 10:55:28 -0800 Subject: [PATCH 053/382] JAVA-1229: Allow specifying the keyspace for individual queries --- changelog/README.md | 1 + .../driver/mapping/AnnotationParser.java | 92 +++--- .../driver/mapping/MappingManager.java | 112 +++++-- .../mapping/MapperDefaultKeyspaceTest.java | 253 ---------------- .../mapping/MapperInvalidAnnotationsTest.java | 28 +- .../driver/mapping/MapperKeyspaceTest.java | 273 ++++++++++++++++++ .../driver/mapping/MapperUDTTest.java | 4 +- 7 files changed, 425 insertions(+), 338 deletions(-) delete mode 100644 driver-mapping/src/test/java/com/datastax/driver/mapping/MapperDefaultKeyspaceTest.java create mode 100644 driver-mapping/src/test/java/com/datastax/driver/mapping/MapperKeyspaceTest.java diff --git a/changelog/README.md b/changelog/README.md index 6e13aae2618..948dae22e02 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -10,6 +10,7 @@ - [improvement] JAVA-1677: Warn if auth is configured on the client but not the server. - [new feature] JAVA-1651: Add NO_COMPACT startup option. - [improvement] JAVA-1683: Add metrics to track writes to nodes. +- [new feature] JAVA-1229: Allow specifying the keyspace for individual queries. Merged from 3.3.x: diff --git a/driver-mapping/src/main/java/com/datastax/driver/mapping/AnnotationParser.java b/driver-mapping/src/main/java/com/datastax/driver/mapping/AnnotationParser.java index d07108209bc..7b8dfac9adc 100644 --- a/driver-mapping/src/main/java/com/datastax/driver/mapping/AnnotationParser.java +++ b/driver-mapping/src/main/java/com/datastax/driver/mapping/AnnotationParser.java @@ -28,12 +28,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -/** - * Static methods that facilitates parsing: - * - {@link #parseEntity(Class, MappingManager)}: entity classes into {@link EntityMapper} instances - * - {@link #parseUDT(Class, MappingManager)}: UDT classes into {@link MappedUDTCodec} instances. - * - {@link #parseAccessor(Class, MappingManager)}: Accessor interfaces into {@link AccessorMapper} instances. - */ class AnnotationParser { private static final Comparator POSITION_COMPARATOR = new Comparator() { @@ -46,37 +40,43 @@ public int compare(AliasedMappedProperty o1, AliasedMappedProperty o2) { private AnnotationParser() { } - static EntityMapper parseEntity(final Class entityClass, MappingManager mappingManager) { + static EntityMapper parseEntity(final Class entityClass, String keyspaceOverride, MappingManager mappingManager) { Table table = AnnotationChecks.getTypeAnnotation(Table.class, entityClass); - String ksName = table.caseSensitiveKeyspace() ? Metadata.quote(table.keyspace()) : table.keyspace().toLowerCase(); + String keyspaceName; + String loggedKeyspace = mappingManager.getSession().getLoggedKeyspace(); + if (!Strings.isNullOrEmpty(keyspaceOverride)) { + keyspaceName = keyspaceOverride; + } else if (!Strings.isNullOrEmpty(table.keyspace())) { + keyspaceName = (table.caseSensitiveKeyspace()) ? Metadata.quote(table.keyspace()) : table.keyspace(); + } else if (!Strings.isNullOrEmpty(loggedKeyspace)) { + keyspaceName = Metadata.quote(loggedKeyspace); + } else { + throw new IllegalArgumentException(String.format( + "Error creating mapper for %s, you must provide a keyspace name " + + "(either as an argument to the MappingManager.mapper() call, " + + "or via the @Table annotation, or by having a default keyspace on your Session)", + entityClass + )); + } + String tableName = table.caseSensitiveTable() ? Metadata.quote(table.name()) : table.name().toLowerCase(); ConsistencyLevel writeConsistency = table.writeConsistency().isEmpty() ? null : ConsistencyLevel.valueOf(table.writeConsistency().toUpperCase()); ConsistencyLevel readConsistency = table.readConsistency().isEmpty() ? null : ConsistencyLevel.valueOf(table.readConsistency().toUpperCase()); - if (Strings.isNullOrEmpty(table.keyspace())) { - String loggedKeyspace = mappingManager.getSession().getLoggedKeyspace(); - if (Strings.isNullOrEmpty(loggedKeyspace)) - throw new IllegalArgumentException(String.format( - "Error creating mapper for %s, the @Table annotation declares no default keyspace, and the session is not currently logged to any keyspace", - entityClass - )); - ksName = Metadata.quote(loggedKeyspace); - } - - KeyspaceMetadata keyspaceMetadata = mappingManager.getSession().getCluster().getMetadata().getKeyspace(ksName); + KeyspaceMetadata keyspaceMetadata = mappingManager.getSession().getCluster().getMetadata().getKeyspace(keyspaceName); if (keyspaceMetadata == null) - throw new IllegalArgumentException(String.format("Keyspace %s does not exist", ksName)); + throw new IllegalArgumentException(String.format("Keyspace %s does not exist", keyspaceName)); AbstractTableMetadata tableMetadata = keyspaceMetadata.getTable(tableName); if (tableMetadata == null) { tableMetadata = keyspaceMetadata.getMaterializedView(tableName); if (tableMetadata == null) - throw new IllegalArgumentException(String.format("Table or materialized view %s does not exist in keyspace %s", tableName, ksName)); + throw new IllegalArgumentException(String.format("Table or materialized view %s does not exist in keyspace %s", tableName, keyspaceName)); } - EntityMapper mapper = new EntityMapper(entityClass, ksName, tableName, writeConsistency, readConsistency); + EntityMapper mapper = new EntityMapper(entityClass, keyspaceName, tableName, writeConsistency, readConsistency); List pks = new ArrayList(); List ccs = new ArrayList(); @@ -99,7 +99,7 @@ static EntityMapper parseEntity(final Class entityClass, MappingManage if (!mappedProperty.isComputed() && tableMetadata.getColumn(mappedProperty.getMappedName()) == null) throw new IllegalArgumentException(String.format("Column %s does not exist in table %s.%s", - mappedProperty.getMappedName(), ksName, tableName)); + mappedProperty.getMappedName(), keyspaceName, tableName)); if (mappedProperty.isPartitionKey()) pks.add(aliasedMappedProperty); @@ -110,7 +110,7 @@ else if (mappedProperty.isClusteringColumn()) // if the property is of a UDT type, parse it now for (Class udt : TypeMappings.findUDTs(mappedProperty.getPropertyType().getType())) - mappingManager.getUDTCodec(udt); + mappingManager.getUDTCodec(udt, keyspaceName); } Collections.sort(pks, POSITION_COMPARATOR); @@ -123,29 +123,35 @@ else if (mappedProperty.isClusteringColumn()) return mapper; } - static MappedUDTCodec parseUDT(Class udtClass, MappingManager mappingManager) { + static MappedUDTCodec parseUDT(Class udtClass, String keyspaceOverride, MappingManager mappingManager) { UDT udt = AnnotationChecks.getTypeAnnotation(UDT.class, udtClass); - String ksName = udt.caseSensitiveKeyspace() ? Metadata.quote(udt.keyspace()) : udt.keyspace().toLowerCase(); - String udtName = udt.caseSensitiveType() ? Metadata.quote(udt.name()) : udt.name().toLowerCase(); - - if (Strings.isNullOrEmpty(udt.keyspace())) { - String loggedKeyspace = mappingManager.getSession().getLoggedKeyspace(); - if (Strings.isNullOrEmpty(loggedKeyspace)) - throw new IllegalArgumentException(String.format( - "Error creating UDT codec for %s, the @UDT annotation declares no default keyspace, and the session is not currently logged to any keyspace", - udtClass - )); - ksName = Metadata.quote(loggedKeyspace); + String keyspaceName; + String loggedKeyspace = mappingManager.getSession().getLoggedKeyspace(); + if (!Strings.isNullOrEmpty(keyspaceOverride)) { + keyspaceName = keyspaceOverride; + } else if (!Strings.isNullOrEmpty(udt.keyspace())) { + keyspaceName = (udt.caseSensitiveKeyspace()) ? Metadata.quote(udt.keyspace()) : udt.keyspace(); + } else if (!Strings.isNullOrEmpty(loggedKeyspace)) { + keyspaceName = Metadata.quote(loggedKeyspace); + } else { + throw new IllegalArgumentException(String.format( + "Error creating mapper for %s, you must provide a keyspace name " + + "(either as an argument to the MappingManager.mapper() call, " + + "or via the @Table annotation, or by having a default keyspace on your Session)", + udtClass + )); } - KeyspaceMetadata keyspaceMetadata = mappingManager.getSession().getCluster().getMetadata().getKeyspace(ksName); + String udtName = udt.caseSensitiveType() ? Metadata.quote(udt.name()) : udt.name().toLowerCase(); + + KeyspaceMetadata keyspaceMetadata = mappingManager.getSession().getCluster().getMetadata().getKeyspace(keyspaceName); if (keyspaceMetadata == null) - throw new IllegalArgumentException(String.format("Keyspace %s does not exist", ksName)); + throw new IllegalArgumentException(String.format("Keyspace %s does not exist", keyspaceName)); UserType userType = keyspaceMetadata.getUserType(udtName); if (userType == null) - throw new IllegalArgumentException(String.format("User type %s does not exist in keyspace %s", udtName, ksName)); + throw new IllegalArgumentException(String.format("User type %s does not exist in keyspace %s", udtName, keyspaceName)); Map propertyMappers = new HashMap(); @@ -158,10 +164,10 @@ static MappedUDTCodec parseUDT(Class udtClass, MappingManager mappingM if (!userType.contains(mappedProperty.getMappedName())) throw new IllegalArgumentException(String.format("Field %s does not exist in type %s.%s", - mappedProperty.getMappedName(), ksName, userType.getTypeName())); + mappedProperty.getMappedName(), keyspaceName, userType.getTypeName())); for (Class fieldUdt : TypeMappings.findUDTs(mappedProperty.getPropertyType().getType())) - mappingManager.getUDTCodec(fieldUdt); + mappingManager.getUDTCodec(fieldUdt, keyspaceName); propertyMappers.put(mappedProperty.getMappedName(), aliasedMappedProperty); } @@ -237,12 +243,12 @@ private static ParamMapper newParamMapper(String className, String methodName, i if (paramType instanceof Class) { Class paramClass = (Class) paramType; if (TypeMappings.isMappedUDT(paramClass)) - mappingManager.getUDTCodec(paramClass); + mappingManager.getUDTCodec(paramClass, null); return new ParamMapper(paramName, idx, TypeToken.of(paramType), codecClass); } else if (paramType instanceof ParameterizedType) { for (Class udt : TypeMappings.findUDTs(paramType)) - mappingManager.getUDTCodec(udt); + mappingManager.getUDTCodec(udt, null); return new ParamMapper(paramName, idx, TypeToken.of(paramType), codecClass); } else { diff --git a/driver-mapping/src/main/java/com/datastax/driver/mapping/MappingManager.java b/driver-mapping/src/main/java/com/datastax/driver/mapping/MappingManager.java index 8514466da8a..0460f13507a 100644 --- a/driver-mapping/src/main/java/com/datastax/driver/mapping/MappingManager.java +++ b/driver-mapping/src/main/java/com/datastax/driver/mapping/MappingManager.java @@ -16,6 +16,7 @@ package com.datastax.driver.mapping; import com.datastax.driver.core.*; +import com.datastax.driver.core.utils.MoreObjects; import com.datastax.driver.mapping.annotations.Accessor; import com.datastax.driver.mapping.annotations.Table; import com.datastax.driver.mapping.annotations.UDT; @@ -24,6 +25,7 @@ import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -38,8 +40,8 @@ public class MappingManager { private final MappingConfiguration configuration; final int protocolVersionAsInt; - private final ConcurrentHashMap, Mapper> mappers = new ConcurrentHashMap, Mapper>(); - private final ConcurrentHashMap, MappedUDTCodec> udtCodecs = new ConcurrentHashMap, MappedUDTCodec>(); + private final ConcurrentHashMap> mappers = new ConcurrentHashMap>(); + private final ConcurrentHashMap> udtCodecs = new ConcurrentHashMap>(); private final ConcurrentHashMap, Object> accessors = new ConcurrentHashMap, Object>(); @@ -164,23 +166,24 @@ public void onUserTypeRemoved(UserType type) { @Override public void onUserTypeChanged(UserType current, UserType previous) { synchronized (udtCodecs) { - Set> deletedCodecs = new HashSet>(); - Iterator> it = udtCodecs.values().iterator(); + Set deletedCodecs = new HashSet(); + Iterator>> it = udtCodecs.entrySet().iterator(); while (it.hasNext()) { - MappedUDTCodec codec = it.next(); + Map.Entry> entry = it.next(); + MappedUDTCodec codec = entry.getValue(); if (previous.equals(codec.getCqlType())) { LOGGER.warn("User type {} has been altered; existing mappers for @UDT annotated {} might not work properly anymore", previous, codec.getUdtClass()); - deletedCodecs.add(codec); + deletedCodecs.add(entry.getKey()); it.remove(); } } - for (MappedUDTCodec deletedCodec : deletedCodecs) { + for (CacheKey key : deletedCodecs) { // try to register an updated version of the previous codec try { - getUDTCodec(deletedCodec.getUdtClass()); + getUDTCodec(key.klass, key.keyspace); } catch (Exception e) { - LOGGER.error("Could not update mapping for @UDT annotated " + deletedCodec.getUdtClass(), e); + LOGGER.error("Could not update mapping for @UDT annotated " + key.klass, e); } } } @@ -217,19 +220,33 @@ public MappingConfiguration getConfiguration() { * Creates a {@code Mapper} for the provided class (that must be annotated by a * {@link Table} annotation). *

- * The {@code MappingManager} only ever keeps one Mapper for each class, and so calling this + * The {@code MappingManager} only ever keeps one Mapper for each class and keyspace, and so calling this * method multiple times on the same class will always return the same object. *

* If the type of any field in the class is an {@link UDT}-annotated classes, a codec for that * class will automatically be created and registered with the underlying {@code Cluster}. * This works recursively with UDTs nested in other UDTs or in collections. * - * @param the type of the class to map. - * @param klass the (annotated) class for which to return the mapper. - * @return the {@code Mapper} object for class {@code klass}. + * @param the type of the class to map. + * @param klass the (annotated) class for which to return the mapper. + * @param keyspace the target keyspace for the mapping (must be quoted if case-sensitive). If this is {@code null}, + * the mapper will try to use the keyspace defined by the annotation, or the default keyspace on the + * session, or fail if neither is declared. + */ + public Mapper mapper(Class klass, String keyspace) { + return getMapper(klass, keyspace); + } + + /** + * Creates a {@code Mapper} for the provided class, using the default keyspace (either the one declared in the + * {@link Table} annotation, or the logged keyspace on the session). + *

+ * This is equivalent to {@code this.mapper(klass, null)}. + * + * @see #mapper(Class, String) */ public Mapper mapper(Class klass) { - return getMapper(klass); + return mapper(klass, null); } /** @@ -243,12 +260,26 @@ public Mapper mapper(Class klass) { * for a class that references this UDT class (creating a mapper will automatically * process all UDTs that it uses). * - * @param the type of the class to map. - * @param klass the (annotated) class for which to return the codec. - * @return the codec that maps the provided class to the corresponding user-defined type. + * @param the type of the class to map. + * @param klass the (annotated) class for which to return the codec. + * @param keyspace the target keyspace for the mapping (must be quoted if case-sensitive). If this is {@code null}, + * the mapper will try to use the keyspace defined by the annotation, or the default keyspace on the + * session, or fail if neither is declared. + */ + public TypeCodec udtCodec(Class klass, String keyspace) { + return getUDTCodec(klass, keyspace); + } + + /** + * Creates a {@code TypeCodec} for the provided class, using the default keyspace (either the one declared in the + * {@link Table} annotation, or the logged keyspace on the session). + *

+ * This is equivalent to {@code this.udtCodec(klass, null)}. + * + * @see #udtCodec(Class, String) */ public TypeCodec udtCodec(Class klass) { - return getUDTCodec(klass); + return udtCodec(klass, null); } /** @@ -267,12 +298,13 @@ public T createAccessor(Class klass) { } @SuppressWarnings("unchecked") - private Mapper getMapper(Class klass) { - Mapper mapper = (Mapper) mappers.get(klass); + private Mapper getMapper(Class klass, String keyspace) { + CacheKey cacheKey = new CacheKey(klass, keyspace); + Mapper mapper = (Mapper) mappers.get(cacheKey); if (mapper == null) { - EntityMapper entityMapper = AnnotationParser.parseEntity(klass, this); + EntityMapper entityMapper = AnnotationParser.parseEntity(klass, keyspace, this); mapper = new Mapper(this, klass, entityMapper); - Mapper old = (Mapper) mappers.putIfAbsent(klass, mapper); + Mapper old = (Mapper) mappers.putIfAbsent(cacheKey, mapper); if (old != null) { mapper = old; } @@ -281,12 +313,13 @@ private Mapper getMapper(Class klass) { } @SuppressWarnings("unchecked") - TypeCodec getUDTCodec(Class mappedClass) { - MappedUDTCodec codec = (MappedUDTCodec) udtCodecs.get(mappedClass); + TypeCodec getUDTCodec(Class mappedClass, String keyspace) { + CacheKey cacheKey = new CacheKey(mappedClass, keyspace); + MappedUDTCodec codec = (MappedUDTCodec) udtCodecs.get(cacheKey); if (codec == null) { - codec = AnnotationParser.parseUDT(mappedClass, this); + codec = AnnotationParser.parseUDT(mappedClass, keyspace, this); session.getCluster().getConfiguration().getCodecRegistry().register(codec); - MappedUDTCodec old = (MappedUDTCodec) udtCodecs.putIfAbsent(mappedClass, codec); + MappedUDTCodec old = (MappedUDTCodec) udtCodecs.putIfAbsent(cacheKey, codec); if (old != null) { codec = old; } @@ -308,4 +341,31 @@ private T getAccessor(Class klass) { } return accessor; } + + private static class CacheKey { + final Class klass; + final String keyspace; + + CacheKey(Class klass, String keyspace) { + this.klass = klass; + this.keyspace = keyspace; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } else if (other instanceof CacheKey) { + CacheKey that = (CacheKey) other; + return this.klass.equals(that.klass) && MoreObjects.equal(this.keyspace, that.keyspace); + } else { + return false; + } + } + + @Override + public int hashCode() { + return MoreObjects.hashCode(klass, keyspace); + } + } } diff --git a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperDefaultKeyspaceTest.java b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperDefaultKeyspaceTest.java deleted file mode 100644 index 9a10cd9606a..00000000000 --- a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperDefaultKeyspaceTest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2012-2017 DataStax Inc. - * - * 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.datastax.driver.mapping; - -import com.datastax.driver.core.CCMTestsSupport; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.utils.CassandraVersion; -import com.datastax.driver.core.utils.MoreObjects; -import com.datastax.driver.core.utils.UUIDs; -import com.datastax.driver.mapping.annotations.*; -import org.testng.annotations.Test; - -import java.util.UUID; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; - -/** - * Tests usage of mapping annotations without specifying a keyspace. - */ -@CassandraVersion("2.1.0") -@SuppressWarnings("unused") -public class MapperDefaultKeyspaceTest extends CCMTestsSupport { - - private static final String KEYSPACE = "mapper_default_keyspace_test_ks"; - - @Override - public void onTestContextInitialized() { - execute( - String.format("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }", KEYSPACE), - String.format("CREATE TYPE IF NOT EXISTS %s.group_name (name text)", KEYSPACE), - String.format("CREATE TABLE IF NOT EXISTS %s.groups (group_id uuid PRIMARY KEY, name text)", KEYSPACE), - String.format("CREATE TABLE IF NOT EXISTS %s.groups2 (group_id uuid PRIMARY KEY, name frozen)", KEYSPACE)); - } - - @Test(groups = "short") - public void testTableWithDefaultKeyspace() throws Exception { - // Ensure that the test session is logged into the keyspace. - session().execute("USE " + KEYSPACE); - - MappingManager manager = new MappingManager(session()); - Mapper m = manager.mapper(Group.class); - Group group = new Group("testGroup"); - UUID groupId = group.getGroupId(); - - // Check the save operation. - m.save(group); - - // Check the select operation. - Group selectedGroup = m.get(groupId); - assertEquals(selectedGroup.getGroupId(), groupId); - - // Check the delete operation. - m.delete(group); - assertNull(m.get(groupId)); - } - - @Test(groups = "short") - public void testUDTWithDefaultKeyspace() throws Exception { - // Ensure that the test session is logged into the keyspace. - session().execute("USE " + KEYSPACE); - - MappingManager manager = new MappingManager(session()); - Mapper m = manager.mapper(Group2.class); - Group2 group = new Group2(new GroupName("testGroup")); - UUID groupId = group.getGroupId(); - - // Check the save operation. - m.save(group); - - // Check the select operation. - Group2 selectedGroup = m.get(groupId); - assertEquals(selectedGroup.getGroupId(), groupId); - - // Check the delete operation. - m.delete(group); - assertNull(m.get(groupId)); - } - - @Test(groups = "short", - expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = "Error creating mapper for class com.datastax.driver.mapping.MapperDefaultKeyspaceTest\\$Group, the @Table annotation declares no default keyspace, and the session is not currently logged to any keyspace") - public void should_throw_a_meaningful_error_message_when_no_default_table_keyspace_and_session_not_logged() { - Session session2 = cluster().connect(); - MappingManager manager = new MappingManager(session2); - manager.mapper(Group.class); - } - - @Test(groups = "short", - expectedExceptions = IllegalArgumentException.class, - expectedExceptionsMessageRegExp = "Error creating UDT codec for class com.datastax.driver.mapping.MapperDefaultKeyspaceTest\\$GroupName, the @UDT annotation declares no default keyspace, and the session is not currently logged to any keyspace") - public void should_throw_a_meaningful_error_message_when_no_default_udt_keyspace_and_session_not_logged() { - Session session2 = cluster().connect(); - MappingManager manager = new MappingManager(session2); - manager.udtCodec(GroupName.class); - } - - - /* - * An entity that does not specify a keyspace in its @Table annotation. When a keyspace is - * not specified, the mapper uses the session's logged in keyspace. - */ - @Table(name = "groups") - public static class Group { - - @PartitionKey - @Column(name = "group_id") - private UUID groupId; - - private String name; - - public Group() { - } - - public Group(String name) { - this.name = name; - this.groupId = UUIDs.random(); - } - - public UUID getGroupId() { - return groupId; - } - - public void setGroupId(UUID groupId) { - this.groupId = groupId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object other) { - if (other == null || other.getClass() != this.getClass()) - return false; - - Group that = (Group) other; - return MoreObjects.equal(groupId, that.groupId) - && MoreObjects.equal(name, that.name); - } - - @Override - public int hashCode() { - return MoreObjects.hashCode(groupId, name); - } - } - - @Table(keyspace = KEYSPACE, name = "groups2") - public static class Group2 { - - @PartitionKey - @Column(name = "group_id") - private UUID groupId; - - @Frozen - private GroupName name; - - public Group2() { - } - - public Group2(GroupName name) { - this.name = name; - this.groupId = UUIDs.random(); - } - - public UUID getGroupId() { - return groupId; - } - - public void setGroupId(UUID groupId) { - this.groupId = groupId; - } - - public GroupName getName() { - return name; - } - - public void setName(GroupName name) { - this.name = name; - } - - @Override - public boolean equals(Object other) { - if (other == null || other.getClass() != this.getClass()) - return false; - - Group2 that = (Group2) other; - return MoreObjects.equal(groupId, that.groupId) - && MoreObjects.equal(name, that.name); - } - - @Override - public int hashCode() { - return MoreObjects.hashCode(groupId, name); - } - } - - /* - * User defined type without a keyspace specified. The mapper will use the session's logged - * keyspace when a keyspace is not specified in the @UDT annotation. - */ - @UDT(name = "group_name") - public static class GroupName { - private String name; - - public GroupName() { - } - - public GroupName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object other) { - if (other instanceof GroupName) { - GroupName that = (GroupName) other; - return this.name.equals(that.name); - } - return false; - } - - @Override - public int hashCode() { - return MoreObjects.hashCode(name); - } - } - -} diff --git a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperInvalidAnnotationsTest.java b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperInvalidAnnotationsTest.java index bdd12c124c0..d2d2b8334bf 100644 --- a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperInvalidAnnotationsTest.java +++ b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperInvalidAnnotationsTest.java @@ -60,7 +60,7 @@ static class Invalid1 { "@Table annotation was not found on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid1") public void should_throw_IAE_when_Table_annotation_not_found_on_entity_class() throws Exception { - AnnotationParser.parseEntity(Invalid1.class, mappingManager); + AnnotationParser.parseEntity(Invalid1.class, null, mappingManager); } @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class, @@ -68,7 +68,7 @@ public void should_throw_IAE_when_Table_annotation_not_found_on_entity_class() t "@UDT annotation was not found on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid1") public void should_throw_IAE_when_UDT_annotation_not_found_on_udt_class() throws Exception { - AnnotationParser.parseUDT(Invalid1.class, mappingManager); + AnnotationParser.parseUDT(Invalid1.class, null, mappingManager); } @Table(name = "foo") @@ -81,7 +81,7 @@ static class Invalid2 { "Cannot have both @Table and @UDT on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid2") public void should_throw_IAE_when_UDT_annotation_found_on_entity_class() throws Exception { - AnnotationParser.parseEntity(Invalid2.class, mappingManager); + AnnotationParser.parseEntity(Invalid2.class, null, mappingManager); } @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class, @@ -89,7 +89,7 @@ public void should_throw_IAE_when_UDT_annotation_found_on_entity_class() throws "Cannot have both @UDT and @Table on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid2") public void should_throw_IAE_when_Table_annotation_found_on_udt_class() throws Exception { - AnnotationParser.parseUDT(Invalid2.class, mappingManager); + AnnotationParser.parseUDT(Invalid2.class, null, mappingManager); } @Table(name = "foo") @@ -102,7 +102,7 @@ static class Invalid3 { "Cannot have both @Table and @Accessor on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid3") public void should_throw_IAE_when_Accessor_annotation_found_on_entity_class() throws Exception { - AnnotationParser.parseEntity(Invalid3.class, mappingManager); + AnnotationParser.parseEntity(Invalid3.class, null, mappingManager); } @UDT(name = "foo") @@ -115,7 +115,7 @@ static class Invalid4 { "Cannot have both @UDT and @Accessor on class " + "com.datastax.driver.mapping.MapperInvalidAnnotationsTest\\$Invalid4") public void should_throw_IAE_when_Accessor_annotation_found_on_udt_class() throws Exception { - AnnotationParser.parseUDT(Invalid4.class, mappingManager); + AnnotationParser.parseUDT(Invalid4.class, null, mappingManager); } @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class, @@ -173,7 +173,7 @@ static class Invalid8 { expectedExceptionsMessageRegExp = "Annotation @Field is not allowed on property 'invalid'") public void should_throw_IAE_when_Field_annotation_found_on_entity_class_field() throws Exception { - AnnotationParser.parseEntity(Invalid8.class, mappingManager); + AnnotationParser.parseEntity(Invalid8.class, null, mappingManager); } @UDT(name = "foo", keyspace = "ks") @@ -191,7 +191,7 @@ public int getInvalid() { expectedExceptionsMessageRegExp = "Annotation @Column is not allowed on property 'invalid'") public void should_throw_IAE_when_Column_annotation_found_on_udt_class_field() throws Exception { - AnnotationParser.parseUDT(Invalid9.class, mappingManager); + AnnotationParser.parseUDT(Invalid9.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -207,7 +207,7 @@ static class Invalid10 { expectedExceptionsMessageRegExp = "Property 'invalid' cannot be annotated with both @PartitionKey and @ClusteringColumn") public void should_throw_IAE_when_PartitionKey_and_ClusteringColumn_on_same_property() throws Exception { - AnnotationParser.parseEntity(Invalid10.class, mappingManager); + AnnotationParser.parseEntity(Invalid10.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -223,7 +223,7 @@ static class Invalid11 { expectedExceptionsMessageRegExp = "Property 'invalid' cannot be annotated with both @Column and @Computed") public void should_throw_IAE_when_Computed_and_Column_on_same_property() throws Exception { - AnnotationParser.parseEntity(Invalid11.class, mappingManager); + AnnotationParser.parseEntity(Invalid11.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -238,7 +238,7 @@ static class Invalid12 { expectedExceptionsMessageRegExp = "Property 'invalid': attribute 'value' of annotation @Computed is mandatory for computed properties") public void should_throw_IAE_when_Computed_with_empty_value() throws Exception { - AnnotationParser.parseEntity(Invalid12.class, mappingManager); + AnnotationParser.parseEntity(Invalid12.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -253,7 +253,7 @@ static class Invalid13 { expectedExceptionsMessageRegExp = "Invalid ordering value -1 for annotation @PartitionKey of property 'invalid', was expecting 0") public void should_throw_IAE_when_PartitionKey_with_wrong_order() throws Exception { - AnnotationParser.parseEntity(Invalid13.class, mappingManager); + AnnotationParser.parseEntity(Invalid13.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -268,7 +268,7 @@ public void setNotReadable(int i) { expectedExceptionsMessageRegExp = "Property 'notReadable' is not readable") public void should_throw_IAE_when_unreadable_property() throws Exception { - AnnotationParser.parseEntity(Invalid14.class, mappingManager); + AnnotationParser.parseEntity(Invalid14.class, null, mappingManager); } @Table(name = "foo", keyspace = "ks") @@ -284,7 +284,7 @@ public int getNotWritable() { expectedExceptionsMessageRegExp = "Property 'notWritable' is not writable") public void should_throw_IAE_when_unwritable_property() throws Exception { - AnnotationParser.parseEntity(Invalid15.class, mappingManager); + AnnotationParser.parseEntity(Invalid15.class, null, mappingManager); } } diff --git a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperKeyspaceTest.java b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperKeyspaceTest.java new file mode 100644 index 00000000000..b5328aeb89c --- /dev/null +++ b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperKeyspaceTest.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.mapping; + +import com.datastax.driver.core.CCMTestsSupport; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.utils.CassandraVersion; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.datastax.driver.mapping.annotations.UDT; +import org.assertj.core.util.Preconditions; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static com.datastax.driver.core.Assertions.assertThat; + +@CassandraVersion("2.0") +public class MapperKeyspaceTest extends CCMTestsSupport { + + @Override + public void onTestContextInitialized() { + execute( + "CREATE KEYSPACE IF NOT EXISTS MapperKeyspaceTest WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}", + "CREATE TYPE IF NOT EXISTS MapperKeyspaceTest.address(street text)", + "CREATE TABLE IF NOT EXISTS MapperKeyspaceTest.user(name text PRIMARY KEY, address frozen

)", + "CREATE KEYSPACE IF NOT EXISTS MapperKeyspaceTest2 WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}", + "CREATE TYPE IF NOT EXISTS MapperKeyspaceTest2.address(street text)", + "CREATE TABLE IF NOT EXISTS MapperKeyspaceTest2.user(name text PRIMARY KEY, address frozen
)" + ); + } + + @BeforeMethod(groups = "short") + public void setup() { + execute("TRUNCATE MapperKeyspaceTest.user", "TRUNCATE MapperKeyspaceTest2.user"); + } + + @Test(groups = "short", expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = ".* you must provide a keyspace name .*") + public void should_fail_if_no_keyspace_provided() { + new TestScenario(UserWithoutKeyspace.class) + .check(); + } + + @Test(groups="short") + public void should_use_session_keyspace() { + // Only works if it's not defined by the annotation + new TestScenario(UserWithoutKeyspace.class) + .withSessionKeyspace("MapperKeyspaceTest") + .withExpectedKeyspace("MapperKeyspaceTest") + .check(); + } + + @Test(groups = "short") + public void should_use_annotation_keyspace() { + new TestScenario(UserWithKeyspace.class) + .withExpectedKeyspace("MapperKeyspaceTest") + .check(); + // Annotation takes precedence over session keyspace: + new TestScenario(UserWithKeyspace.class) + .withSessionKeyspace("MapperKeyspaceTest2") + .withExpectedKeyspace("MapperKeyspaceTest") + .check(); + } + + @Test(groups = "short") + public void should_use_keyspace_provided_when_creating_mapper() { + // Provided nowhere except in the mapper call: + new TestScenario(UserWithoutKeyspace.class) + .withMapperKeyspace("MapperKeyspaceTest") + .withExpectedKeyspace("MapperKeyspaceTest") + .check(); + // Mapper takes precedence over session: + new TestScenario(UserWithoutKeyspace.class) + .withSessionKeyspace("MapperKeyspaceTest") + .withMapperKeyspace("MapperKeyspaceTest2") + .withExpectedKeyspace("MapperKeyspaceTest2") + .check(); + // Mapper takes precedence over annotation: + new TestScenario(UserWithKeyspace.class) + .withMapperKeyspace("MapperKeyspaceTest2") + .withExpectedKeyspace("MapperKeyspaceTest2") + .check(); + } + + private class TestScenario { + + private final Class userClass; + private final UserT sampleUser; + + private String sessionKeyspace; + private String mapperKeyspace; + private String expectedKeyspace; + + TestScenario(Class userClass) { + this.userClass = userClass; + this.sampleUser = buildSampleUser(userClass); + } + + @SuppressWarnings("unchecked") + private UserT buildSampleUser(Class userClass) { + // Hacky but we know the subclasses so no need to be more fancy + if (userClass == UserWithKeyspace.class) { + return (UserT) new UserWithKeyspace("user1", new AddressWithKeyspace("street")); + } else if (userClass == UserWithoutKeyspace.class) { + return (UserT) new UserWithoutKeyspace("user1", new AddressWithoutKeyspace("street")); + } else { + throw new AssertionError("Unsupported user class " + userClass); + } + } + + /** + * The keyspace passed to Cluster.connect() + */ + TestScenario withSessionKeyspace(String sessionKeyspace) { + this.sessionKeyspace = sessionKeyspace; + return this; + } + + /** + * The keyspace passed to MappingManager.mapper() + */ + TestScenario withMapperKeyspace(String mapperKeyspace) { + this.mapperKeyspace = mapperKeyspace; + return this; + } + + /** + * The keyspace where we expect data to be saved + */ + TestScenario withExpectedKeyspace(String expectedKeyspace) { + this.expectedKeyspace = expectedKeyspace; + return this; + } + + void check() { + Session session = cluster().connect(sessionKeyspace); + MappingManager manager = new MappingManager(session); + Mapper mapper = manager.mapper(userClass, mapperKeyspace); + + mapper.save(sampleUser); + assertThat(expectedKeyspace).isNotNull(); + Row row = session().execute(String.format("SELECT * FROM %s.user WHERE name = ?", expectedKeyspace), sampleUser.getName()).one(); + assertThat(row).isNotNull(); + + UserT loadedUser = mapper.get(sampleUser.getName()); + assertThat(loadedUser.getName()).isEqualTo(sampleUser.getName()); + assertThat(loadedUser.getAddress().getStreet()).isEqualTo(sampleUser.getAddress().getStreet()); + + mapper.delete(sampleUser); + row = session().execute(String.format("SELECT * FROM %s.user WHERE name = ?", expectedKeyspace), sampleUser.getName()).one(); + assertThat(row).isNull(); + } + } + + @SuppressWarnings("unused") + public static class Address { + private String street; + + public Address() { + } + + public Address(String street) { + this.street = street; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + } + + @SuppressWarnings("unused") + @UDT(keyspace = "MapperKeyspaceTest", name = "address") + public static class AddressWithKeyspace extends Address { + public AddressWithKeyspace() { + } + + public AddressWithKeyspace(String street) { + super(street); + } + } + + @SuppressWarnings("unused") + @UDT(name = "address") + public static class AddressWithoutKeyspace extends Address { + public AddressWithoutKeyspace() { + } + + public AddressWithoutKeyspace(String street) { + super(street); + } + } + + @SuppressWarnings("unused") + public static class User { + @PartitionKey + private String name; + private AddressT address; + + public User() { + } + + public User(String name, AddressT address) { + this.name = name; + this.address = address; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public AddressT getAddress() { + return address; + } + + public void setAddress(AddressT address) { + this.address = address; + } + } + + @SuppressWarnings("unused") + @Table(keyspace = "MapperKeyspaceTest", name = "user") + public static class UserWithKeyspace extends User { + public UserWithKeyspace() { + } + + public UserWithKeyspace(String name, AddressWithKeyspace address) { + super(name, address); + } + + @Override + public AddressWithKeyspace getAddress() { + return super.getAddress(); + } + } + + @SuppressWarnings("unused") + @Table(name = "user") + public static class UserWithoutKeyspace extends User { + public UserWithoutKeyspace() { + } + + public UserWithoutKeyspace(String name, AddressWithoutKeyspace address) { + super(name, address); + } + + @Override + public AddressWithoutKeyspace getAddress() { + return super.getAddress(); + } + } +} diff --git a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperUDTTest.java b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperUDTTest.java index 1288609e5a1..0ff7f39a559 100644 --- a/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperUDTTest.java +++ b/driver-mapping/src/test/java/com/datastax/driver/mapping/MapperUDTTest.java @@ -626,7 +626,7 @@ public void setProvince(String province) { @Test(groups = "short", expectedExceptions = IllegalArgumentException.class) public void should_fail_to_create_codec_if_class_has_field_not_in_udt() { MappingManager manager = new MappingManager(session()); - manager.getUDTCodec(AddressUnknownField.class); + manager.getUDTCodec(AddressUnknownField.class, keyspace); } @UDT(name = "nonexistent") @@ -652,7 +652,7 @@ public String getName() { @Test(groups = "short", expectedExceptions = IllegalArgumentException.class) public void should_fail_to_create_codec_if_udt_does_not_exist() { MappingManager manager = new MappingManager(session()); - manager.getUDTCodec(NonExistentUDT.class); + manager.getUDTCodec(NonExistentUDT.class, keyspace); } @Table(name = "users") From 13ac1762dfda44e45f9411a69a495dc8aacd2fdc Mon Sep 17 00:00:00 2001 From: olim7t Date: Thu, 16 Nov 2017 13:44:37 -0800 Subject: [PATCH 054/382] JAVA-1682: Provide a way to record latencies for cancelled speculative executions Those latencies are emitted with a CancelledSpeculativeExecutionException, which allows LatencyTracker implementations to choose whether to include them or not. For example, a tracker that wants to detect "slowness" of a node might want to record them (otherwise a node that always hits the speculative execution threshold would appear to have no measurement), whereas a tracker that monitors latencies of successful executions should ignore them. --- changelog/README.md | 1 + ...ancelledSpeculativeExecutionException.java | 29 +++++++++++++++++++ .../driver/core/PercentileTracker.java | 3 +- .../datastax/driver/core/RequestHandler.java | 9 ++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 driver-core/src/main/java/com/datastax/driver/core/CancelledSpeculativeExecutionException.java diff --git a/changelog/README.md b/changelog/README.md index 948dae22e02..496a051c743 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -11,6 +11,7 @@ - [new feature] JAVA-1651: Add NO_COMPACT startup option. - [improvement] JAVA-1683: Add metrics to track writes to nodes. - [new feature] JAVA-1229: Allow specifying the keyspace for individual queries. +- [improvement] JAVA-1682: Provide a way to record latencies for cancelled speculative executions. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/CancelledSpeculativeExecutionException.java b/driver-core/src/main/java/com/datastax/driver/core/CancelledSpeculativeExecutionException.java new file mode 100644 index 00000000000..6ee22899128 --- /dev/null +++ b/driver-core/src/main/java/com/datastax/driver/core/CancelledSpeculativeExecutionException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-2017 DataStax Inc. + * + * 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.datastax.driver.core; + +/** + * Special exception that gets emitted to {@link LatencyTracker}s with the latencies of cancelled speculative + * executions. This allows those trackers to choose whether to ignore those latencies or not. + */ +class CancelledSpeculativeExecutionException extends Exception { + + static CancelledSpeculativeExecutionException INSTANCE = new CancelledSpeculativeExecutionException(); + + private CancelledSpeculativeExecutionException() { + super(); + } +} diff --git a/driver-core/src/main/java/com/datastax/driver/core/PercentileTracker.java b/driver-core/src/main/java/com/datastax/driver/core/PercentileTracker.java index 6f60df2f1b2..1f554af75ea 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/PercentileTracker.java +++ b/driver-core/src/main/java/com/datastax/driver/core/PercentileTracker.java @@ -255,7 +255,8 @@ protected boolean include(Host host, Statement statement, Exception exception) { OverloadedException.class, BootstrappingException.class, UnpreparedException.class, - QueryValidationException.class // query validation also happens at early stages in the coordinator + QueryValidationException.class, // query validation also happens at early stages in the coordinator + CancelledSpeculativeExecutionException.class ); /** diff --git a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java index 97a45f9d3dc..6afa44f57f4 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java +++ b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java @@ -274,6 +274,7 @@ class SpeculativeExecution implements Connection.ResponseCallback { private volatile ConsistencyLevel retryConsistencyLevel; private final AtomicReference queryStateRef; private final AtomicBoolean nextExecutionScheduled = new AtomicBoolean(); + private final long startTime = System.nanoTime(); // This represents the number of times a retry has been triggered by the RetryPolicy (this is different from // queryStateRef.get().retryCount, because some retries don't involve the policy, for example after an @@ -511,10 +512,18 @@ void cancel() { // If it's still null, this will be handled by re-checking queryStateRef at the end of write(). if (connectionHandler != null && connectionHandler.cancelHandler()) connectionHandler.connection.release(); + Host queriedHost = current; + if (queriedHost != null && statement != Statement.DEFAULT) { + manager.cluster.manager.reportQuery(queriedHost, statement, CancelledSpeculativeExecutionException.INSTANCE, System.nanoTime() - startTime); + } return; } else if (!previous.inProgress && queryStateRef.compareAndSet(previous, QueryState.CANCELLED_WHILE_COMPLETE)) { if (logger.isTraceEnabled()) logger.trace("[{}] Cancelled while complete", id); + Host queriedHost = current; + if (queriedHost != null && statement != Statement.DEFAULT) { + manager.cluster.manager.reportQuery(queriedHost, statement, CancelledSpeculativeExecutionException.INSTANCE, System.nanoTime() - startTime); + } return; } } From 6f16812b7b08037a5671ed232df096981453f94e Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 8 Jan 2018 09:57:47 -0800 Subject: [PATCH 055/382] JAVA-1717: Add metrics to latency-aware policy --- changelog/README.md | 1 + .../core/policies/LatencyAwarePolicy.java | 73 +++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 496a051c743..67017998db1 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -12,6 +12,7 @@ - [improvement] JAVA-1683: Add metrics to track writes to nodes. - [new feature] JAVA-1229: Allow specifying the keyspace for individual queries. - [improvement] JAVA-1682: Provide a way to record latencies for cancelled speculative executions. +- [improvement] JAVA-1717: Add metrics to latency-aware policy. Merged from 3.3.x: diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java index dc9b876e1d3..866fa184f40 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java @@ -15,6 +15,7 @@ */ package com.datastax.driver.core.policies; +import com.codahale.metrics.Gauge; import com.datastax.driver.core.*; import com.datastax.driver.core.exceptions.*; import com.google.common.annotations.VisibleForTesting; @@ -62,6 +63,7 @@ public class LatencyAwarePolicy implements ChainableLoadBalancingPolicy { private static final Logger logger = LoggerFactory.getLogger(LatencyAwarePolicy.class); + private static final boolean HOST_METRICS_ENABLED = Boolean.getBoolean("com.datastax.driver.HOST_METRICS_ENABLED"); private final LoadBalancingPolicy childPolicy; private final Tracker latencyTracker; @@ -72,6 +74,7 @@ public class LatencyAwarePolicy implements ChainableLoadBalancingPolicy { private final long scale; private final long retryPeriod; private final long minMeasure; + private volatile Metrics metrics; private LatencyAwarePolicy(LoadBalancingPolicy childPolicy, double exclusionThreshold, @@ -176,6 +179,17 @@ private static ThreadFactory threadFactory(String nameFormat) { public void init(Cluster cluster, Collection hosts) { childPolicy.init(cluster, hosts); cluster.register(latencyTracker); + metrics = cluster.getMetrics(); + if (metrics != null) { + metrics.getRegistry().register( + "LatencyAwarePolicy.latencies.min", + new Gauge() { + @Override + public Long getValue() { + return latencyTracker.getMinAverage(); + } + }); + } } /** @@ -219,21 +233,45 @@ protected Host computeNext() { // If we haven't had enough data point yet to have a score, or the last update of the score // is just too old, include the host. - if (min < 0 || latency == null || latency.nbMeasure < minMeasure || (now - latency.timestamp) > retryPeriod) + if (min < 0 || latency == null || latency.nbMeasure < minMeasure || (now - latency.timestamp) > retryPeriod) { + if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.inclusions-nodata.", host)) + .inc(); + } return host; + } // If the host latency is within acceptable bound of the faster known host, return // that host. Otherwise, skip it. - if (latency.average <= ((long) (exclusionThreshold * (double) min))) + if (latency.average <= ((long) (exclusionThreshold * (double) min))) { + if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.inclusions.", host)) + .inc(); + } return host; + } if (skipped == null) skipped = new ArrayDeque(); skipped.offer(host); + if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.exclusions.", host)) + .inc(); + } } - if (skipped != null && !skipped.isEmpty()) - return skipped.poll(); + if (skipped != null && !skipped.isEmpty()) { + Host host = skipped.poll(); + if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.hits-while-excluded.", host)) + .inc(); + } + return host; + } return endOfData(); } @@ -384,16 +422,35 @@ private class Tracker implements LatencyTracker { private volatile long cachedMin = -1L; @Override - public void update(Host host, Statement statement, Exception exception, long newLatencyNanos) { + public void update(final Host host, Statement statement, Exception exception, long newLatencyNanos) { if (shouldConsiderNewLatency(statement, exception)) { HostLatencyTracker hostTracker = latencies.get(host); if (hostTracker == null) { hostTracker = new HostLatencyTracker(scale, (30L * minMeasure) / 100L); HostLatencyTracker old = latencies.putIfAbsent(host, hostTracker); - if (old != null) + if (old != null) { hostTracker = old; + } else if (hostMetricsEnabled()) { + String metricName = MetricsUtil.hostMetricName("LatencyAwarePolicy.latencies.", host); + if (!metrics.getRegistry().getNames().contains(metricName)) { + logger.info("Adding gauge " + metricName); + metrics.getRegistry().register( + metricName, + new Gauge() { + @Override + public Long getValue() { + TimestampedAverage latency = latencyTracker.latencyOf(host); + return (latency == null) ? -1 : latency.average; + } + }); + } + } } hostTracker.add(newLatencyNanos); + } else if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.ignored-latencies.", host)) + .inc(); } } @@ -719,4 +776,8 @@ public void close() { childPolicy.close(); updaterService.shutdown(); } + + private boolean hostMetricsEnabled() { + return HOST_METRICS_ENABLED && metrics != null; + } } From 4281d0710666d6b8d408da50110b6031764cf2dd Mon Sep 17 00:00:00 2001 From: olim7t Date: Mon, 8 Jan 2018 10:37:35 -0800 Subject: [PATCH 056/382] Add host tracker in onUp/onAdd This avoids a race when onDown/onRemove removes the tracker, but pending requests complete after that and re-add it. --- .../core/policies/LatencyAwarePolicy.java | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java index 866fa184f40..fc6c4cf2276 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/LatencyAwarePolicy.java @@ -178,6 +178,9 @@ private static ThreadFactory threadFactory(String nameFormat) { @Override public void init(Cluster cluster, Collection hosts) { childPolicy.init(cluster, hosts); + for (Host host : hosts) { + latencyTracker.addHost(host); + } cluster.register(latencyTracker); metrics = cluster.getMetrics(); if (metrics != null) { @@ -303,6 +306,7 @@ public Snapshot getScoresSnapshot() { @Override public void onUp(Host host) { childPolicy.onUp(host); + latencyTracker.addHost(host); } @Override @@ -314,6 +318,7 @@ public void onDown(Host host) { @Override public void onAdd(Host host) { childPolicy.onAdd(host); + latencyTracker.addHost(host); } @Override @@ -423,34 +428,15 @@ private class Tracker implements LatencyTracker { @Override public void update(final Host host, Statement statement, Exception exception, long newLatencyNanos) { - if (shouldConsiderNewLatency(statement, exception)) { - HostLatencyTracker hostTracker = latencies.get(host); - if (hostTracker == null) { - hostTracker = new HostLatencyTracker(scale, (30L * minMeasure) / 100L); - HostLatencyTracker old = latencies.putIfAbsent(host, hostTracker); - if (old != null) { - hostTracker = old; - } else if (hostMetricsEnabled()) { - String metricName = MetricsUtil.hostMetricName("LatencyAwarePolicy.latencies.", host); - if (!metrics.getRegistry().getNames().contains(metricName)) { - logger.info("Adding gauge " + metricName); - metrics.getRegistry().register( - metricName, - new Gauge() { - @Override - public Long getValue() { - TimestampedAverage latency = latencyTracker.latencyOf(host); - return (latency == null) ? -1 : latency.average; - } - }); - } - } + HostLatencyTracker hostTracker = latencies.get(host); + if (hostTracker != null) { + if (shouldConsiderNewLatency(statement, exception)) { + hostTracker.add(newLatencyNanos); + } else if (hostMetricsEnabled()) { + metrics.getRegistry() + .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.ignored-latencies.", host)) + .inc(); } - hostTracker.add(newLatencyNanos); - } else if (hostMetricsEnabled()) { - metrics.getRegistry() - .counter(MetricsUtil.hostMetricName("LatencyAwarePolicy.ignored-latencies.", host)) - .inc(); } } @@ -490,7 +476,29 @@ public Map currentLatencies() { return map; } + public void addHost(final Host host) { + logger.debug("Adding tracker for {}", host); + HostLatencyTracker old = latencies.putIfAbsent(host, + new HostLatencyTracker(scale, (30L * minMeasure) / 100L)); + if (old == null && hostMetricsEnabled()) { + String metricName = MetricsUtil.hostMetricName("LatencyAwarePolicy.latencies.", host); + if (!metrics.getRegistry().getNames().contains(metricName)) { + logger.debug("Adding gauge " + metricName); + metrics.getRegistry().register( + metricName, + new Gauge() { + @Override + public Long getValue() { + TimestampedAverage latency = latencyTracker.latencyOf(host); + return (latency == null) ? -1 : latency.average; + } + }); + } + } + } + public void resetHost(Host host) { + logger.debug("Removing tracker for {}", host); latencies.remove(host); } From 5f4067ba005648bfa7b51678db1dec3d090edd1e Mon Sep 17 00:00:00 2001 From: olim7t Date: Thu, 11 Jan 2018 17:36:37 -0800 Subject: [PATCH 057/382] JAVA-1675: Remove dates from copyright headers --- changelog/README.md | 1 + driver-core/pom.xml | 2 +- .../core/AbstractAddressableByIndexData.java | 2 +- .../com/datastax/driver/core/AbstractData.java | 2 +- .../driver/core/AbstractGettableByIndexData.java | 2 +- .../driver/core/AbstractGettableData.java | 2 +- .../core/AbstractMonotonicTimestampGenerator.java | 2 +- .../driver/core/AbstractReconnectionHandler.java | 2 +- .../com/datastax/driver/core/AbstractSession.java | 2 +- .../driver/core/AbstractTableMetadata.java | 2 +- .../datastax/driver/core/AggregateMetadata.java | 2 +- .../driver/core/ArrayBackedResultSet.java | 2 +- .../com/datastax/driver/core/ArrayBackedRow.java | 2 +- .../core/AtomicMonotonicTimestampGenerator.java | 2 +- .../com/datastax/driver/core/AuthProvider.java | 2 +- .../com/datastax/driver/core/Authenticator.java | 2 +- .../com/datastax/driver/core/BatchStatement.java | 2 +- .../com/datastax/driver/core/BoundStatement.java | 2 +- .../java/com/datastax/driver/core/CBUtil.java | 2 +- .../CancelledSpeculativeExecutionException.java | 2 +- .../driver/core/ChainedResultSetFuture.java | 2 +- .../main/java/com/datastax/driver/core/Clock.java | 2 +- .../com/datastax/driver/core/CloseFuture.java | 2 +- .../java/com/datastax/driver/core/Cluster.java | 2 +- .../driver/core/ClusterNameMismatchException.java | 2 +- .../driver/core/ClusterWidePercentileTracker.java | 2 +- .../com/datastax/driver/core/ClusteringOrder.java | 2 +- .../com/datastax/driver/core/CodecRegistry.java | 2 +- .../java/com/datastax/driver/core/CodecUtils.java | 2 +- .../datastax/driver/core/ColumnDefinitions.java | 2 +- .../com/datastax/driver/core/ColumnMetadata.java | 2 +- .../com/datastax/driver/core/Configuration.java | 2 +- .../java/com/datastax/driver/core/Connection.java | 2 +- .../datastax/driver/core/ConsistencyLevel.java | 2 +- .../datastax/driver/core/ControlConnection.java | 2 +- .../datastax/driver/core/ConvictionPolicy.java | 2 +- .../java/com/datastax/driver/core/DataType.java | 2 +- .../driver/core/DataTypeClassNameParser.java | 2 +- .../driver/core/DataTypeCqlNameParser.java | 2 +- .../driver/core/DefaultPreparedStatement.java | 2 +- .../driver/core/DefaultResultSetFuture.java | 2 +- .../datastax/driver/core/DelegatingCluster.java | 2 +- .../com/datastax/driver/core/DirectedGraph.java | 2 +- .../datastax/driver/core/DriverThrowables.java | 2 +- .../java/com/datastax/driver/core/Duration.java | 2 +- .../com/datastax/driver/core/EventDebouncer.java | 2 +- .../driver/core/ExceptionCatchingRunnable.java | 2 +- .../com/datastax/driver/core/ExceptionCode.java | 2 +- .../com/datastax/driver/core/ExecutionInfo.java | 2 +- .../main/java/com/datastax/driver/core/Frame.java | 2 +- .../com/datastax/driver/core/FrameCompressor.java | 2 +- .../datastax/driver/core/FunctionMetadata.java | 2 +- .../datastax/driver/core/GettableByIndexData.java | 2 +- .../datastax/driver/core/GettableByNameData.java | 2 +- .../com/datastax/driver/core/GettableData.java | 2 +- .../datastax/driver/core/GuavaCompatibility.java | 2 +- .../main/java/com/datastax/driver/core/Host.java | 2 +- .../datastax/driver/core/HostConnectionPool.java | 2 +- .../com/datastax/driver/core/HostDistance.java | 2 +- .../com/datastax/driver/core/IndexMetadata.java | 2 +- .../com/datastax/driver/core/JdkSSLOptions.java | 2 +- .../datastax/driver/core/KeyspaceMetadata.java | 2 +- .../com/datastax/driver/core/LZ4Compressor.java | 2 +- .../com/datastax/driver/core/LatencyTracker.java | 2 +- .../java/com/datastax/driver/core/LocalDate.java | 2 +- .../core/LoggingMonotonicTimestampGenerator.java | 2 +- .../java/com/datastax/driver/core/MD5Digest.java | 2 +- .../driver/core/MaterializedViewMetadata.java | 2 +- .../java/com/datastax/driver/core/Message.java | 2 +- .../java/com/datastax/driver/core/Metadata.java | 2 +- .../java/com/datastax/driver/core/Metrics.java | 2 +- .../com/datastax/driver/core/MetricsOptions.java | 2 +- .../com/datastax/driver/core/MetricsUtil.java | 2 +- .../java/com/datastax/driver/core/Native.java | 2 +- .../com/datastax/driver/core/NettyOptions.java | 2 +- .../com/datastax/driver/core/NettySSLOptions.java | 2 +- .../java/com/datastax/driver/core/NettyUtil.java | 2 +- .../com/datastax/driver/core/PagingIterable.java | 2 +- .../com/datastax/driver/core/PagingState.java | 2 +- .../java/com/datastax/driver/core/ParseUtils.java | 2 +- .../driver/core/PerHostPercentileTracker.java | 2 +- .../datastax/driver/core/PercentileTracker.java | 2 +- .../driver/core/PlainTextAuthProvider.java | 2 +- .../com/datastax/driver/core/PoolingOptions.java | 2 +- .../java/com/datastax/driver/core/PreparedId.java | 2 +- .../datastax/driver/core/PreparedStatement.java | 2 +- .../com/datastax/driver/core/ProtocolEvent.java | 2 +- .../com/datastax/driver/core/ProtocolFeature.java | 2 +- .../com/datastax/driver/core/ProtocolOptions.java | 2 +- .../driver/core/ProtocolV1Authenticator.java | 2 +- .../com/datastax/driver/core/ProtocolVersion.java | 2 +- .../com/datastax/driver/core/QueryLogger.java | 2 +- .../com/datastax/driver/core/QueryOptions.java | 2 +- .../java/com/datastax/driver/core/QueryTrace.java | 2 +- .../datastax/driver/core/RegularStatement.java | 2 +- .../core/RemoteEndpointAwareJdkSSLOptions.java | 2 +- .../core/RemoteEndpointAwareNettySSLOptions.java | 2 +- .../core/RemoteEndpointAwareSSLOptions.java | 2 +- .../datastax/driver/core/ReplicationStategy.java | 2 +- .../com/datastax/driver/core/RequestHandler.java | 2 +- .../java/com/datastax/driver/core/Requests.java | 2 +- .../java/com/datastax/driver/core/Responses.java | 2 +- .../java/com/datastax/driver/core/ResultSet.java | 2 +- .../com/datastax/driver/core/ResultSetFuture.java | 2 +- .../main/java/com/datastax/driver/core/Row.java | 2 +- .../java/com/datastax/driver/core/SSLOptions.java | 2 +- .../driver/core/SchemaChangeListener.java | 2 +- .../driver/core/SchemaChangeListenerBase.java | 2 +- .../com/datastax/driver/core/SchemaElement.java | 2 +- .../com/datastax/driver/core/SchemaParser.java | 2 +- .../driver/core/ServerSideTimestampGenerator.java | 2 +- .../java/com/datastax/driver/core/Session.java | 2 +- .../com/datastax/driver/core/SessionManager.java | 2 +- .../datastax/driver/core/SettableByIndexData.java | 2 +- .../datastax/driver/core/SettableByNameData.java | 2 +- .../com/datastax/driver/core/SettableData.java | 2 +- .../datastax/driver/core/SimpleJSONParser.java | 2 +- .../com/datastax/driver/core/SimpleStatement.java | 2 +- .../datastax/driver/core/SnappyCompressor.java | 2 +- .../com/datastax/driver/core/SocketOptions.java | 2 +- .../java/com/datastax/driver/core/Statement.java | 2 +- .../datastax/driver/core/StatementWrapper.java | 2 +- .../datastax/driver/core/StreamIdGenerator.java | 2 +- .../datastax/driver/core/SystemProperties.java | 2 +- .../com/datastax/driver/core/TableMetadata.java | 2 +- .../driver/core/TableOptionsMetadata.java | 2 +- .../ThreadLocalMonotonicTimestampGenerator.java | 2 +- .../datastax/driver/core/ThreadingOptions.java | 2 +- .../datastax/driver/core/TimestampGenerator.java | 2 +- .../main/java/com/datastax/driver/core/Token.java | 2 +- .../java/com/datastax/driver/core/TokenRange.java | 2 +- .../java/com/datastax/driver/core/TupleType.java | 2 +- .../java/com/datastax/driver/core/TupleValue.java | 2 +- .../java/com/datastax/driver/core/TypeCodec.java | 2 +- .../java/com/datastax/driver/core/TypeTokens.java | 2 +- .../java/com/datastax/driver/core/UDTValue.java | 2 +- .../java/com/datastax/driver/core/UserType.java | 2 +- .../java/com/datastax/driver/core/VIntCoding.java | 2 +- .../com/datastax/driver/core/VersionNumber.java | 2 +- .../java/com/datastax/driver/core/WriteType.java | 2 +- .../core/exceptions/AlreadyExistsException.java | 2 +- .../core/exceptions/AuthenticationException.java | 2 +- .../core/exceptions/BootstrappingException.java | 2 +- .../core/exceptions/BusyConnectionException.java | 2 +- .../driver/core/exceptions/BusyPoolException.java | 2 +- .../core/exceptions/CodecNotFoundException.java | 2 +- .../core/exceptions/ConnectionException.java | 2 +- .../core/exceptions/CoordinatorException.java | 2 +- .../driver/core/exceptions/DriverException.java | 2 +- .../core/exceptions/DriverInternalError.java | 2 +- .../core/exceptions/FrameTooLongException.java | 2 +- .../exceptions/FunctionExecutionException.java | 2 +- .../InvalidConfigurationInQueryException.java | 2 +- .../core/exceptions/InvalidQueryException.java | 2 +- .../core/exceptions/InvalidTypeException.java | 2 +- .../core/exceptions/NoHostAvailableException.java | 2 +- .../exceptions/OperationTimedOutException.java | 2 +- .../core/exceptions/OverloadedException.java | 2 +- .../core/exceptions/PagingStateException.java | 2 +- .../driver/core/exceptions/ProtocolError.java | 2 +- .../exceptions/QueryConsistencyException.java | 2 +- .../core/exceptions/QueryExecutionException.java | 2 +- .../core/exceptions/QueryValidationException.java | 2 +- .../core/exceptions/ReadFailureException.java | 2 +- .../core/exceptions/ReadTimeoutException.java | 2 +- .../driver/core/exceptions/ServerError.java | 2 +- .../driver/core/exceptions/SyntaxError.java | 2 +- .../core/exceptions/TraceRetrievalException.java | 2 +- .../core/exceptions/TransportException.java | 2 +- .../driver/core/exceptions/TruncateException.java | 2 +- .../core/exceptions/UnauthorizedException.java | 2 +- .../core/exceptions/UnavailableException.java | 2 +- .../core/exceptions/UnpreparedException.java | 2 +- .../exceptions/UnresolvedUserTypeException.java | 2 +- .../exceptions/UnsupportedFeatureException.java | 2 +- .../UnsupportedProtocolVersionException.java | 2 +- .../core/exceptions/WriteFailureException.java | 2 +- .../core/exceptions/WriteTimeoutException.java | 2 +- .../driver/core/exceptions/package-info.java | 2 +- .../com/datastax/driver/core/package-info.java | 2 +- .../driver/core/policies/AddressTranslator.java | 2 +- .../policies/ChainableLoadBalancingPolicy.java | 2 +- .../com/datastax/driver/core/policies/Clock.java | 2 +- .../core/policies/ConstantReconnectionPolicy.java | 2 +- .../ConstantSpeculativeExecutionPolicy.java | 2 +- .../core/policies/DCAwareRoundRobinPolicy.java | 2 +- .../driver/core/policies/DefaultRetryPolicy.java | 2 +- .../DowngradingConsistencyRetryPolicy.java | 2 +- .../policies/EC2MultiRegionAddressTranslator.java | 2 +- .../driver/core/policies/ErrorAwarePolicy.java | 2 +- .../policies/ExponentialReconnectionPolicy.java | 2 +- .../core/policies/FallthroughRetryPolicy.java | 2 +- .../driver/core/policies/HostFilterPolicy.java | 2 +- .../policies/IdempotenceAwareRetryPolicy.java | 2 +- .../driver/core/policies/IdentityTranslator.java | 2 +- .../driver/core/policies/LatencyAwarePolicy.java | 2 +- .../driver/core/policies/LoadBalancingPolicy.java | 2 +- .../driver/core/policies/LoggingRetryPolicy.java | 2 +- .../policies/NoSpeculativeExecutionPolicy.java | 2 +- .../PercentileSpeculativeExecutionPolicy.java | 2 +- .../datastax/driver/core/policies/Policies.java | 2 +- .../driver/core/policies/ReconnectionPolicy.java | 2 +- .../driver/core/policies/RetryPolicy.java | 2 +- .../driver/core/policies/RollingCount.java | 2 +- .../driver/core/policies/RoundRobinPolicy.java | 2 +- .../core/policies/SpeculativeExecutionPolicy.java | 2 +- .../driver/core/policies/TokenAwarePolicy.java | 2 +- .../driver/core/policies/WhiteListPolicy.java | 2 +- .../driver/core/policies/package-info.java | 2 +- .../driver/core/querybuilder/Assignment.java | 2 +- .../datastax/driver/core/querybuilder/Batch.java | 2 +- .../driver/core/querybuilder/BindMarker.java | 2 +- .../driver/core/querybuilder/BuiltStatement.java | 2 +- .../datastax/driver/core/querybuilder/Clause.java | 2 +- .../datastax/driver/core/querybuilder/Delete.java | 2 +- .../datastax/driver/core/querybuilder/Insert.java | 2 +- .../driver/core/querybuilder/Ordering.java | 2 +- .../driver/core/querybuilder/QueryBuilder.java | 2 +- .../datastax/driver/core/querybuilder/Select.java | 2 +- .../driver/core/querybuilder/Truncate.java | 2 +- .../datastax/driver/core/querybuilder/Update.java | 2 +- .../datastax/driver/core/querybuilder/Using.java | 2 +- .../datastax/driver/core/querybuilder/Utils.java | 2 +- .../driver/core/querybuilder/package-info.java | 2 +- .../schemabuilder/AbstractCreateStatement.java | 2 +- .../datastax/driver/core/schemabuilder/Alter.java | 2 +- .../driver/core/schemabuilder/AlterKeyspace.java | 2 +- .../driver/core/schemabuilder/ColumnType.java | 2 +- .../driver/core/schemabuilder/Create.java | 2 +- .../driver/core/schemabuilder/CreateIndex.java | 2 +- .../driver/core/schemabuilder/CreateKeyspace.java | 2 +- .../driver/core/schemabuilder/CreateType.java | 2 +- .../datastax/driver/core/schemabuilder/Drop.java | 2 +- .../driver/core/schemabuilder/DropKeyspace.java | 2 +- .../core/schemabuilder/KeyspaceOptions.java | 2 +- .../core/schemabuilder/NativeColumnType.java | 2 +- .../driver/core/schemabuilder/SchemaBuilder.java | 2 +- .../core/schemabuilder/SchemaStatement.java | 2 +- .../driver/core/schemabuilder/StatementStart.java | 2 +- .../driver/core/schemabuilder/TableOptions.java | 2 +- .../driver/core/schemabuilder/UDTType.java | 2 +- .../driver/core/schemabuilder/package-info.java | 2 +- .../com/datastax/driver/core/utils/Bytes.java | 2 +- .../datastax/driver/core/utils/MoreFutures.java | 2 +- .../datastax/driver/core/utils/MoreObjects.java | 2 +- .../com/datastax/driver/core/utils/UUIDs.java | 2 +- .../com/datastax/driver/core/Driver.properties | 2 +- .../driver/core/AbstractBatchIdempotencyTest.java | 2 +- .../driver/core/AbstractPoliciesTest.java | 2 +- .../core/AbstractReconnectionHandlerTest.java | 2 +- .../core/AbstractReplicationStrategyTest.java | 2 +- .../driver/core/AggregateMetadataAssert.java | 2 +- .../driver/core/AggregateMetadataTest.java | 2 +- .../java/com/datastax/driver/core/Assertions.java | 2 +- .../com/datastax/driver/core/AsyncQueryTest.java | 2 +- .../datastax/driver/core/AsyncResultSetTest.java | 2 +- .../AtomicMonotonicTimestampGeneratorTest.java | 2 +- .../datastax/driver/core/AuthenticationTest.java | 2 +- .../core/BatchStatementIdempotencyTest.java | 2 +- .../datastax/driver/core/BatchStatementTest.java | 2 +- .../datastax/driver/core/BoundStatementTest.java | 2 +- .../java/com/datastax/driver/core/CCMAccess.java | 2 +- .../java/com/datastax/driver/core/CCMBridge.java | 2 +- .../com/datastax/driver/core/CCMBridgeTest.java | 2 +- .../java/com/datastax/driver/core/CCMCache.java | 2 +- .../java/com/datastax/driver/core/CCMConfig.java | 2 +- .../com/datastax/driver/core/CCMException.java | 2 +- .../com/datastax/driver/core/CCMTestsSupport.java | 2 +- .../com/datastax/driver/core/CCMWorkload.java | 2 +- .../datastax/driver/core/CaseSensitivityTest.java | 2 +- .../datastax/driver/core/ClockFactoryTest.java | 2 +- .../com/datastax/driver/core/ClusterAssert.java | 2 +- .../com/datastax/driver/core/ClusterInitTest.java | 2 +- .../datastax/driver/core/ClusterStressTest.java | 2 +- .../core/ClusterWidePercentileTrackerTest.java | 2 +- .../datastax/driver/core/CodecRegistryTest.java | 2 +- .../driver/core/ColumnDefinitionsAssert.java | 2 +- .../driver/core/ColumnDefinitionsTest.java | 2 +- .../driver/core/ColumnMetadataAssert.java | 2 +- .../com/datastax/driver/core/CompressionTest.java | 2 +- .../datastax/driver/core/ConditionChecker.java | 2 +- .../driver/core/ConditionalUpdateTest.java | 2 +- .../driver/core/ConnectionReleaseTest.java | 2 +- .../com/datastax/driver/core/ConsistencyTest.java | 2 +- .../driver/core/ControlConnectionTest.java | 2 +- .../driver/core/CountingReconnectionPolicy.java | 2 +- .../java/com/datastax/driver/core/CreateCCM.java | 2 +- .../datastax/driver/core/CustomPayloadTest.java | 2 +- .../driver/core/CustomPercentileTrackerTest.java | 2 +- .../com/datastax/driver/core/CustomTypeTest.java | 2 +- .../com/datastax/driver/core/DataProviders.java | 2 +- .../com/datastax/driver/core/DataTypeAssert.java | 2 +- .../driver/core/DataTypeClassNameParserTest.java | 2 +- .../driver/core/DataTypeCqlNameParserTest.java | 2 +- .../driver/core/DataTypeIntegrationTest.java | 2 +- .../com/datastax/driver/core/DataTypeTest.java | 2 +- .../core/DelegatingClusterIntegrationTest.java | 2 +- .../driver/core/DelegatingClusterTest.java | 2 +- .../driver/core/DirectCompressionTest.java | 2 +- .../datastax/driver/core/DirectedGraphTest.java | 2 +- .../datastax/driver/core/DseCCMClusterTest.java | 2 +- .../datastax/driver/core/DurationCodecTest.java | 2 +- .../driver/core/DurationIntegrationTest.java | 2 +- .../com/datastax/driver/core/DurationTest.java | 2 +- .../core/EventDebouncerIntegrationTest.java | 2 +- .../datastax/driver/core/EventDebouncerTest.java | 2 +- .../datastax/driver/core/ExportAsStringTest.java | 2 +- .../core/ExtendedPeerCheckDisabledTest.java | 2 +- .../java/com/datastax/driver/core/FakeHost.java | 2 +- .../com/datastax/driver/core/FetchingTest.java | 2 +- .../com/datastax/driver/core/FrameLengthTest.java | 2 +- .../driver/core/FunctionMetadataAssert.java | 2 +- .../driver/core/FunctionMetadataTest.java | 2 +- .../driver/core/GettableDataIntegrationTest.java | 2 +- .../datastax/driver/core/HeapCompressionTest.java | 2 +- .../com/datastax/driver/core/HeartbeatTest.java | 2 +- .../java/com/datastax/driver/core/HostAssert.java | 2 +- .../driver/core/HostConnectionPoolMultiTest.java | 2 +- .../driver/core/HostConnectionPoolTest.java | 2 +- .../driver/core/HostMetadataIntegrationTest.java | 2 +- .../datastax/driver/core/IndexMetadataAssert.java | 2 +- .../datastax/driver/core/IndexMetadataTest.java | 2 +- .../driver/core/Jdk8SSLEncryptionTest.java | 2 +- .../driver/core/KeyspaceMetadataAssert.java | 2 +- .../com/datastax/driver/core/LargeDataTest.java | 2 +- .../core/LoadBalancingPolicyBootstrapTest.java | 2 +- .../core/LoadBalancingPolicyRefreshTest.java | 2 +- .../com/datastax/driver/core/LocalDateAssert.java | 2 +- .../com/datastax/driver/core/LocalDateTest.java | 2 +- .../datastax/driver/core/M3PTokenFactoryTest.java | 2 +- .../driver/core/M3PTokenIntegrationTest.java | 2 +- .../driver/core/M3PTokenVnodeIntegrationTest.java | 2 +- .../com/datastax/driver/core/MappingCodec.java | 2 +- .../core/MaterializedViewMetadataAssert.java | 2 +- .../driver/core/MaterializedViewMetadataTest.java | 2 +- .../com/datastax/driver/core/MemoryAppender.java | 2 +- .../com/datastax/driver/core/MetadataTest.java | 2 +- .../datastax/driver/core/MetricsInFlightTest.java | 2 +- .../com/datastax/driver/core/MetricsTest.java | 2 +- .../driver/core/MissingRpcAddressTest.java | 2 +- .../java/com/datastax/driver/core/MockClocks.java | 2 +- .../datastax/driver/core/NettyOptionsTest.java | 2 +- .../driver/core/NetworkTopologyStrategyTest.java | 2 +- .../driver/core/NoAuthenticationTest.java | 2 +- .../driver/core/NodeListRefreshDebouncerTest.java | 2 +- .../driver/core/NodeRefreshDebouncerTest.java | 2 +- .../datastax/driver/core/OPPTokenFactoryTest.java | 2 +- .../driver/core/OPPTokenIntegrationTest.java | 2 +- .../driver/core/OPPTokenVnodeIntegrationTest.java | 2 +- .../com/datastax/driver/core/PagingStateTest.java | 2 +- .../com/datastax/driver/core/ParseUtilsTest.java | 2 +- .../driver/core/PerHostPercentileTrackerTest.java | 2 +- .../driver/core/PercentileTrackerTest.java | 2 +- .../core/PoolingOptionsIntegrationTest.java | 2 +- .../datastax/driver/core/PoolingOptionsTest.java | 2 +- .../com/datastax/driver/core/PreparedIdTest.java | 2 +- .../core/PreparedStatementInvalidationTest.java | 15 +++++++++++++++ .../driver/core/PreparedStatementTest.java | 2 +- .../driver/core/PrimitiveTypeSamples.java | 2 +- .../driver/core/ProtocolBetaVersionTest.java | 2 +- .../datastax/driver/core/ProtocolOptionsTest.java | 2 +- .../com/datastax/driver/core/ProtocolV1Test.java | 2 +- .../core/ProtocolVersionRenegotiationTest.java | 2 +- .../driver/core/QueryLoggerErrorsTest.java | 2 +- .../com/datastax/driver/core/QueryLoggerTest.java | 2 +- .../datastax/driver/core/QueryOptionsTest.java | 2 +- .../datastax/driver/core/QueryTimestampTest.java | 2 +- .../com/datastax/driver/core/QueryTracker.java | 2 +- .../datastax/driver/core/RPTokenFactoryTest.java | 2 +- .../driver/core/RPTokenIntegrationTest.java | 2 +- .../driver/core/RPTokenVnodeIntegrationTest.java | 2 +- .../com/datastax/driver/core/ReadTimeoutTest.java | 2 +- .../driver/core/RecommissionedNodeTest.java | 2 +- .../driver/core/ReconnectionPolicyTest.java | 2 +- .../datastax/driver/core/ReconnectionTest.java | 2 +- .../driver/core/RefreshConnectedHostTest.java | 2 +- .../driver/core/ReplicationStrategyTest.java | 2 +- .../datastax/driver/core/RequestHandlerTest.java | 2 +- .../com/datastax/driver/core/ResultSetAssert.java | 2 +- .../datastax/driver/core/ReusedStreamIdTest.java | 2 +- .../core/SSLAuthenticatedEncryptionTest.java | 2 +- .../datastax/driver/core/SSLEncryptionTest.java | 2 +- .../com/datastax/driver/core/SSLTestBase.java | 2 +- .../datastax/driver/core/ScassandraCluster.java | 2 +- .../datastax/driver/core/ScassandraTestBase.java | 2 +- .../datastax/driver/core/SchemaAgreementTest.java | 2 +- .../datastax/driver/core/SchemaChangesCCTest.java | 2 +- .../datastax/driver/core/SchemaChangesTest.java | 2 +- .../driver/core/SchemaRefreshDebouncerTest.java | 2 +- .../com/datastax/driver/core/SessionAssert.java | 2 +- .../datastax/driver/core/SessionErrorTest.java | 2 +- .../com/datastax/driver/core/SessionLeakTest.java | 2 +- .../datastax/driver/core/SessionStressTest.java | 2 +- .../com/datastax/driver/core/SessionTest.java | 2 +- .../driver/core/SimpleJSONParserTest.java | 2 +- .../core/SimpleStatementIntegrationTest.java | 2 +- .../datastax/driver/core/SimpleStatementTest.java | 2 +- .../datastax/driver/core/SimpleStrategyTest.java | 2 +- .../driver/core/SingleConnectionPoolTest.java | 2 +- .../driver/core/SingleTokenIntegrationTest.java | 2 +- .../driver/core/SortingLoadBalancingPolicy.java | 2 +- .../driver/core/SpeculativeExecutionTest.java | 2 +- .../datastax/driver/core/StateListenerBase.java | 2 +- .../datastax/driver/core/StateListenerTest.java | 2 +- .../driver/core/StatementIdempotenceTest.java | 2 +- .../driver/core/StatementWrapperTest.java | 2 +- .../driver/core/StreamIdGeneratorTest.java | 2 +- .../datastax/driver/core/TableMetadataAssert.java | 2 +- .../driver/core/TableMetadataCDCTest.java | 2 +- .../datastax/driver/core/TableMetadataTest.java | 2 +- .../com/datastax/driver/core/TestListener.java | 2 +- .../java/com/datastax/driver/core/TestUtils.java | 2 +- ...hreadLocalMonotonicTimestampGeneratorTest.java | 2 +- .../driver/core/ThreadingOptionsTest.java | 2 +- .../datastax/driver/core/TimeoutStressTest.java | 2 +- .../driver/core/TokenIntegrationTest.java | 2 +- .../datastax/driver/core/TokenRangeAssert.java | 2 +- .../com/datastax/driver/core/TokenRangeTest.java | 2 +- .../com/datastax/driver/core/TracingTest.java | 2 +- .../java/com/datastax/driver/core/TupleTest.java | 2 +- .../com/datastax/driver/core/TypeCodecAssert.java | 2 +- .../core/TypeCodecCollectionsIntegrationTest.java | 2 +- .../TypeCodecEncapsulationIntegrationTest.java | 2 +- ...TypeCodecNestedCollectionsIntegrationTest.java | 2 +- ...TypeCodecNestedUDTAndTupleIntegrationTest.java | 2 +- .../core/TypeCodecNumbersIntegrationTest.java | 2 +- ...peCodecOverlappingJavaTypeIntegrationTest.java | 2 +- .../com/datastax/driver/core/TypeCodecTest.java | 2 +- .../core/TypeCodecTupleIntegrationTest.java | 2 +- .../driver/core/TypeCodecUDTIntegrationTest.java | 2 +- .../driver/core/UnresolvedUserTypeTest.java | 2 +- .../com/datastax/driver/core/UserTypesTest.java | 2 +- .../datastax/driver/core/VersionNumberAssert.java | 2 +- .../datastax/driver/core/VersionNumberTest.java | 2 +- .../com/datastax/driver/core/WarningsTest.java | 2 +- .../core/exceptions/ConnectionExceptionTest.java | 2 +- .../core/exceptions/ExceptionsScassandraTest.java | 2 +- .../driver/core/exceptions/ExceptionsTest.java | 2 +- .../FunctionExecutionExceptionTest.java | 2 +- .../exceptions/NoHostAvailableExceptionTest.java | 2 +- .../exceptions/ReadWriteFailureExceptionTest.java | 2 +- .../AbstractRetryPolicyIntegrationTest.java | 2 +- .../CloseableLoadBalancingPolicyTest.java | 2 +- .../CustomRetryPolicyIntegrationTest.java | 2 +- .../policies/DCAwareRoundRobinPolicyTest.java | 2 +- .../DefaultRetryPolicyIntegrationTest.java | 2 +- .../policies/DelegatingLoadBalancingPolicy.java | 2 +- .../DelegatingSpeculativeExecutionPolicy.java | 2 +- ...dingConsistencyRetryPolicyIntegrationTest.java | 2 +- .../EC2MultiRegionAddressTranslatorTest.java | 2 +- .../policies/ErrorAwarePolicyIntegrationTest.java | 2 +- .../FallthroughRetryPolicyIntegrationTest.java | 2 +- .../core/policies/HostFilterPolicyTest.java | 2 +- ...dempotenceAwareRetryPolicyIntegrationTest.java | 2 +- .../core/policies/LatencyAwarePolicyTest.java | 2 +- .../policies/LimitingLoadBalancingPolicy.java | 2 +- .../LoggingRetryPolicyIntegrationTest.java | 2 +- .../driver/core/policies/RetryDecisionTest.java | 2 +- .../driver/core/policies/RollingCountTest.java | 2 +- .../core/policies/RoundRobinPolicyTest.java | 2 +- .../core/policies/TokenAwarePolicyTest.java | 2 +- .../driver/core/policies/WhiteListPolicyTest.java | 2 +- .../core/querybuilder/BatchIdempotencyTest.java | 2 +- .../querybuilder/QueryBuilder21ExecutionTest.java | 2 +- .../querybuilder/QueryBuilderExecutionTest.java | 2 +- .../core/querybuilder/QueryBuilderITest.java | 2 +- .../querybuilder/QueryBuilderRoutingKeyTest.java | 2 +- .../core/querybuilder/QueryBuilderTest.java | 2 +- .../QueryBuilderTupleExecutionTest.java | 2 +- .../QueryBuilderUDTExecutionTest.java | 2 +- .../core/schemabuilder/AlterKeyspaceTest.java | 2 +- .../driver/core/schemabuilder/AlterTest.java | 2 +- .../core/schemabuilder/CompactionOptionsTest.java | 2 +- .../schemabuilder/CompressionOptionsTest.java | 2 +- .../core/schemabuilder/CreateIndexTest.java | 2 +- .../core/schemabuilder/CreateKeyspaceTest.java | 2 +- .../driver/core/schemabuilder/CreateTest.java | 2 +- .../driver/core/schemabuilder/CreateTypeTest.java | 2 +- .../core/schemabuilder/DropKeyspaceTest.java | 2 +- .../driver/core/schemabuilder/DropTest.java | 2 +- .../core/schemabuilder/SchemaBuilderIT.java | 2 +- .../driver/core/utils/CassandraVersion.java | 2 +- .../datastax/driver/core/utils/DseVersion.java | 2 +- .../driver/core/utils/SocketChannelMonitor.java | 2 +- .../core/utils/UUIDsPIDFromPropertyTest.java | 2 +- .../driver/core/utils/UUIDsPIDNativeTest.java | 2 +- .../core/utils/UUIDsPIDPropertyInvalidTest.java | 2 +- .../com/datastax/driver/core/utils/UUIDsTest.java | 2 +- driver-core/src/test/resources/log4j.properties | 2 +- driver-dist/pom.xml | 2 +- driver-dist/src/assembly/binary-tarball.xml | 2 +- driver-examples/pom.xml | 2 +- .../examples/basic/CreateAndPopulateKeyspace.java | 2 +- .../examples/basic/ReadCassandraVersion.java | 2 +- .../basic/ReadTopologyAndSchemaMetadata.java | 2 +- .../datastax/driver/examples/datatypes/Blobs.java | 2 +- .../driver/examples/json/JacksonJsonColumn.java | 2 +- .../driver/examples/json/JacksonJsonFunction.java | 2 +- .../driver/examples/json/JacksonJsonRow.java | 2 +- .../driver/examples/json/Jsr353JsonColumn.java | 2 +- .../driver/examples/json/Jsr353JsonFunction.java | 2 +- .../driver/examples/json/Jsr353JsonRow.java | 2 +- .../driver/examples/json/PlainTextJson.java | 2 +- .../examples/paging/ForwardPagingRestUi.java | 2 +- .../examples/paging/RandomPagingRestUi.java | 2 +- driver-examples/src/main/resources/logback.xml | 2 +- driver-extras/pom.xml | 2 +- .../driver/extras/codecs/MappingCodec.java | 2 +- .../driver/extras/codecs/ParsingCodec.java | 2 +- .../extras/codecs/arrays/AbstractArrayCodec.java | 2 +- .../arrays/AbstractPrimitiveArrayCodec.java | 2 +- .../extras/codecs/arrays/DoubleArrayCodec.java | 2 +- .../extras/codecs/arrays/FloatArrayCodec.java | 2 +- .../extras/codecs/arrays/IntArrayCodec.java | 2 +- .../extras/codecs/arrays/LongArrayCodec.java | 2 +- .../extras/codecs/arrays/ObjectArrayCodec.java | 2 +- .../driver/extras/codecs/arrays/package-info.java | 2 +- .../extras/codecs/date/SimpleDateCodec.java | 2 +- .../extras/codecs/date/SimpleTimestampCodec.java | 2 +- .../driver/extras/codecs/date/package-info.java | 2 +- .../driver/extras/codecs/enums/EnumNameCodec.java | 2 +- .../extras/codecs/enums/EnumOrdinalCodec.java | 2 +- .../driver/extras/codecs/enums/package-info.java | 2 +- .../driver/extras/codecs/guava/OptionalCodec.java | 2 +- .../driver/extras/codecs/guava/package-info.java | 2 +- .../extras/codecs/jdk8/IgnoreJDK6Requirement.java | 2 +- .../driver/extras/codecs/jdk8/InstantCodec.java | 2 +- .../driver/extras/codecs/jdk8/LocalDateCodec.java | 2 +- .../driver/extras/codecs/jdk8/LocalTimeCodec.java | 2 +- .../driver/extras/codecs/jdk8/OptionalCodec.java | 2 +- .../extras/codecs/jdk8/ZonedDateTimeCodec.java | 2 +- .../driver/extras/codecs/jdk8/package-info.java | 2 +- .../driver/extras/codecs/joda/DateTimeCodec.java | 2 +- .../driver/extras/codecs/joda/InstantCodec.java | 2 +- .../driver/extras/codecs/joda/LocalDateCodec.java | 2 +- .../driver/extras/codecs/joda/LocalTimeCodec.java | 2 +- .../driver/extras/codecs/joda/package-info.java | 2 +- .../extras/codecs/json/JacksonJsonCodec.java | 2 +- .../extras/codecs/json/Jsr353JsonCodec.java | 2 +- .../driver/extras/codecs/json/package-info.java | 2 +- .../driver/extras/codecs/package-info.java | 2 +- .../extras/codecs/arrays/ArrayCodecsTest.java | 2 +- .../extras/codecs/date/SimpleDateCodecTest.java | 2 +- .../extras/codecs/date/SimpleDateCodecsTest.java | 2 +- .../codecs/date/SimpleTimestampCodecTest.java | 2 +- .../extras/codecs/enums/EnumCodecsTest.java | 2 +- .../extras/codecs/guava/OptionalCodecTest.java | 2 +- .../extras/codecs/jdk8/InstantCodecTest.java | 2 +- .../extras/codecs/jdk8/Jdk8TimeCodecsTest.java | 2 +- .../extras/codecs/jdk8/LocalDateCodecTest.java | 2 +- .../extras/codecs/jdk8/LocalTimeCodecTest.java | 2 +- .../extras/codecs/jdk8/OptionalCodecTest.java | 2 +- .../codecs/jdk8/ZonedDateTimeCodecTest.java | 2 +- .../extras/codecs/joda/DateTimeCodecTest.java | 2 +- .../extras/codecs/joda/InstantCodecTest.java | 2 +- .../extras/codecs/joda/JodaTimeCodecsTest.java | 2 +- .../extras/codecs/joda/LocalDateCodecTest.java | 2 +- .../extras/codecs/joda/LocalTimeCodecTest.java | 2 +- .../extras/codecs/json/JacksonJsonCodecTest.java | 2 +- .../extras/codecs/json/Jsr353JsonCodecTest.java | 2 +- driver-extras/src/test/resources/log4j.properties | 2 +- driver-mapping/pom.xml | 2 +- .../driver/mapping/AccessorInvocationHandler.java | 2 +- .../datastax/driver/mapping/AccessorMapper.java | 2 +- .../driver/mapping/AliasedMappedProperty.java | 2 +- .../datastax/driver/mapping/AnnotationChecks.java | 2 +- .../datastax/driver/mapping/AnnotationParser.java | 2 +- .../mapping/DefaultHierarchyScanStrategy.java | 2 +- .../driver/mapping/DefaultMappedProperty.java | 2 +- .../driver/mapping/DefaultNamingStrategy.java | 2 +- .../driver/mapping/DefaultPropertyMapper.java | 2 +- .../datastax/driver/mapping/DriverThrowables.java | 2 +- .../com/datastax/driver/mapping/EntityMapper.java | 2 +- .../driver/mapping/HierarchyScanStrategy.java | 2 +- .../MappedClassesOnlyHierarchyScanStrategy.java | 2 +- .../datastax/driver/mapping/MappedProperty.java | 2 +- .../datastax/driver/mapping/MappedUDTCodec.java | 2 +- .../java/com/datastax/driver/mapping/Mapper.java | 2 +- .../driver/mapping/MapperBoundStatement.java | 2 +- .../driver/mapping/MappingConfiguration.java | 2 +- .../datastax/driver/mapping/MappingManager.java | 2 +- .../com/datastax/driver/mapping/MethodMapper.java | 2 +- .../datastax/driver/mapping/NamingConvention.java | 2 +- .../driver/mapping/NamingConventions.java | 2 +- .../datastax/driver/mapping/NamingStrategy.java | 2 +- .../driver/mapping/PropertyAccessStrategy.java | 2 +- .../datastax/driver/mapping/PropertyMapper.java | 2 +- .../mapping/PropertyTransienceStrategy.java | 2 +- .../com/datastax/driver/mapping/QueryType.java | 2 +- .../datastax/driver/mapping/ReflectionUtils.java | 2 +- .../java/com/datastax/driver/mapping/Result.java | 2 +- .../com/datastax/driver/mapping/TypeMappings.java | 2 +- .../java/com/datastax/driver/mapping/Word.java | 2 +- .../driver/mapping/annotations/Accessor.java | 2 +- .../mapping/annotations/ClusteringColumn.java | 2 +- .../driver/mapping/annotations/Column.java | 2 +- .../driver/mapping/annotations/Computed.java | 2 +- .../driver/mapping/annotations/Defaults.java | 2 +- .../driver/mapping/annotations/Field.java | 2 +- .../driver/mapping/annotations/Frozen.java | 2 +- .../driver/mapping/annotations/FrozenKey.java | 2 +- .../driver/mapping/annotations/FrozenValue.java | 2 +- .../driver/mapping/annotations/Param.java | 2 +- .../driver/mapping/annotations/PartitionKey.java | 2 +- .../driver/mapping/annotations/Query.java | 2 +- .../mapping/annotations/QueryParameters.java | 2 +- .../driver/mapping/annotations/Table.java | 2 +- .../driver/mapping/annotations/Transient.java | 2 +- .../datastax/driver/mapping/annotations/UDT.java | 2 +- .../driver/mapping/MapperAccessorParamsTest.java | 2 +- .../driver/mapping/MapperAccessorTest.java | 2 +- .../driver/mapping/MapperAsyncResultTest.java | 2 +- .../datastax/driver/mapping/MapperAsyncTest.java | 2 +- .../driver/mapping/MapperCaseSensitivityTest.java | 2 +- .../driver/mapping/MapperCompositeKeyTest.java | 2 +- .../driver/mapping/MapperComputedFieldsTest.java | 2 +- .../driver/mapping/MapperCustomCodecTest.java | 2 +- .../mapping/MapperInvalidAnnotationsTest.java | 2 +- .../driver/mapping/MapperKeyspaceTest.java | 2 +- .../mapping/MapperMaterializedViewTest.java | 2 +- .../mapping/MapperNestedCollectionsTest.java | 2 +- .../driver/mapping/MapperNestedUDTTest.java | 2 +- .../datastax/driver/mapping/MapperOptionTest.java | 2 +- .../driver/mapping/MapperPolymorphismTest.java | 2 +- .../mapping/MapperPrimitiveTypes22Test.java | 2 +- .../driver/mapping/MapperPrimitiveTypesTest.java | 2 +- .../driver/mapping/MapperReconnectionTest.java | 2 +- .../driver/mapping/MapperSaveNullFieldsTest.java | 2 +- .../com/datastax/driver/mapping/MapperTest.java | 2 +- .../driver/mapping/MapperUDTCollectionsTest.java | 2 +- .../datastax/driver/mapping/MapperUDTTest.java | 2 +- ...ingConfigurationHierarchyScanStrategyTest.java | 2 +- .../MappingConfigurationNamingStrategyTest.java | 2 +- .../MappingConfigurationPropertyAccessTest.java | 2 +- ...appingConfigurationTransienceStrategyTest.java | 2 +- .../MappingConfigurationTransientTest.java | 2 +- .../driver/mapping/NamingConventionsTest.java | 2 +- .../driver/mapping/SyntheticFieldsMapperTest.java | 2 +- .../driver/mapping/UDTFieldMapperTest.java | 2 +- .../src/test/resources/log4j.properties | 2 +- driver-tests/osgi/pom.xml | 2 +- .../driver/osgi/api/MailboxException.java | 2 +- .../datastax/driver/osgi/api/MailboxMessage.java | 2 +- .../datastax/driver/osgi/api/MailboxService.java | 2 +- .../com/datastax/driver/osgi/impl/Activator.java | 2 +- .../datastax/driver/osgi/impl/MailboxImpl.java | 2 +- .../com/datastax/driver/osgi/BundleOptions.java | 2 +- .../datastax/driver/osgi/CCMBridgeListener.java | 2 +- .../driver/osgi/MailboxServiceDefaultIT.java | 2 +- .../driver/osgi/MailboxServiceGuava17IT.java | 2 +- .../driver/osgi/MailboxServiceGuava18IT.java | 2 +- .../driver/osgi/MailboxServiceGuava19IT.java | 2 +- .../driver/osgi/MailboxServiceGuava20IT.java | 2 +- .../driver/osgi/MailboxServiceGuava21IT.java | 2 +- .../driver/osgi/MailboxServiceHdrHistogramIT.java | 2 +- .../datastax/driver/osgi/MailboxServiceLZ4IT.java | 2 +- .../driver/osgi/MailboxServiceShadedIT.java | 2 +- .../driver/osgi/MailboxServiceSnappyIT.java | 2 +- .../datastax/driver/osgi/MailboxServiceTests.java | 2 +- .../osgi/src/test/resources/exam.properties | 2 +- driver-tests/osgi/src/test/resources/logback.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- .../com/datastax/driver/core/NettyUtilIT.java | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- .../com/datastax/driver/core/NettyUtilIT.java | 2 +- driver-tests/stress/pom.xml | 2 +- .../driver/stress/AsynchronousConsumer.java | 2 +- .../datastax/driver/stress/BlockingConsumer.java | 2 +- .../driver/stress/ConsistencyLevelConverter.java | 2 +- .../java/com/datastax/driver/stress/Consumer.java | 2 +- .../com/datastax/driver/stress/Generators.java | 2 +- .../datastax/driver/stress/QueryGenerator.java | 2 +- .../java/com/datastax/driver/stress/Reporter.java | 2 +- .../java/com/datastax/driver/stress/Stress.java | 2 +- pom.xml | 4 ++-- 677 files changed, 692 insertions(+), 676 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 67017998db1..fcd718c395a 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -13,6 +13,7 @@ - [new feature] JAVA-1229: Allow specifying the keyspace for individual queries. - [improvement] JAVA-1682: Provide a way to record latencies for cancelled speculative executions. - [improvement] JAVA-1717: Add metrics to latency-aware policy. +- [improvement] JAVA-1675: Remove dates from copyright headers. Merged from 3.3.x: diff --git a/driver-core/pom.xml b/driver-core/pom.xml index c773c3ee7c8..173c1f244f6 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -1,6 +1,6 @@ -[Metrics]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.html \ No newline at end of file +[Metrics]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Metrics.html \ No newline at end of file diff --git a/manual/native_protocol/README.md b/manual/native_protocol/README.md index be945e75664..fbab41473f2 100644 --- a/manual/native_protocol/README.md +++ b/manual/native_protocol/README.md @@ -63,7 +63,7 @@ All host(s) tried for query failed [/127.0.0.1:9042] Host /127.0.0.1:9042 does not support protocol version V3 but V2)) ``` -[gpv]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- +[gpv]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- #### Protocol version with mixed clusters @@ -94,19 +94,19 @@ To avoid this issue, you can use one the following workarounds: #### v1 to v2 * bound variables in simple statements - ([Session#execute(String, Object...)](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-java.lang.String-java.lang.Object...-)) -* [batch statements](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html) + ([Session#execute(String, Object...)](http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#execute-java.lang.String-java.lang.Object...-)) +* [batch statements](http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/BatchStatement.html) * [query paging](../paging/) #### v2 to v3 * the number of stream ids per connection goes from 128 to 32768 (see [Connection pooling](../pooling/)) -* [serial consistency on batch statements](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html#setSerialConsistencyLevel-com.datastax.driver.core.ConsistencyLevel-) +* [serial consistency on batch statements](http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/BatchStatement.html#setSerialConsistencyLevel-com.datastax.driver.core.ConsistencyLevel-) * [client-side timestamps](../query_timestamps/) #### v3 to v4 -* [query warnings](http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ExecutionInfo.html#getWarnings--) +* [query warnings](http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ExecutionInfo.html#getWarnings--) * allowed unset values in bound statements * [Custom payloads](../custom_payloads/) diff --git a/manual/object_mapper/README.md b/manual/object_mapper/README.md index 08e5f18797a..4c51d6b442b 100644 --- a/manual/object_mapper/README.md +++ b/manual/object_mapper/README.md @@ -11,7 +11,7 @@ The mapper is published as a separate Maven artifact: com.datastax.cassandra cassandra-driver-mapping - 3.3.0 + 3.4.0 ``` diff --git a/manual/object_mapper/creating/README.md b/manual/object_mapper/creating/README.md index cbb14bf2244..ed74cee44f5 100644 --- a/manual/object_mapper/creating/README.md +++ b/manual/object_mapper/creating/README.md @@ -149,9 +149,9 @@ User user = new User() .setName("John Doe"); ``` -[table]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Table.html +[table]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Table.html [case-sensitive]:http://docs.datastax.com/en/cql/3.3/cql/cql_reference/ucase-lcase_r.html -[consistency level]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ConsistencyLevel.html +[consistency level]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ConsistencyLevel.html [java-beans]:https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html [set-accessible]:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean- @@ -189,7 +189,7 @@ CREATE TABLE users(id uuid PRIMARY KEY, "userName" text); private String userName; ``` -[column]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Column.html +[column]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Column.html #### Primary key fields @@ -213,8 +213,8 @@ private String areaCode; The order of the indices must match that of the columns in the table declaration. -[pk]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/PartitionKey.html -[cc]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/ClusteringColumn.html +[pk]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/PartitionKey.html +[cc]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/ClusteringColumn.html [pks]:http://thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html #### Computed fields @@ -250,7 +250,7 @@ version (see [JAVA-832](https://datastax-oss.atlassian.net/browse/JAVA-832)). [User Defined Functions]:http://www.planetcassandra.org/blog/user-defined-functions-in-cassandra-3-0/ -[computed]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Computed.html +[computed]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Computed.html #### Transient properties @@ -259,7 +259,7 @@ to table columns. [@Transient][transient] can be used to prevent a field or a Java bean property from being mapped. Like other column-level annotations, it should be placed on either the field declaration or the property getter method. -[transient]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Transient.html +[transient]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Transient.html ### Mapping User Types @@ -322,8 +322,8 @@ This also works with UDTs inside collections or other UDTs, with any arbitrary nesting level. [User Defined Types]: ../../udts/ -[udt]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/UDT.html -[field]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Field.html +[udt]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/UDT.html +[field]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Field.html ### Mapping collections @@ -359,9 +359,9 @@ private Map> frozenKeyValueMap; private Map> frozenValueMap; ``` -[frozen]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Frozen.html -[frozenkey]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/FrozenKey.html -[frozenvalue]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/FrozenValue.html +[frozen]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Frozen.html +[frozenkey]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/FrozenKey.html +[frozenvalue]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/FrozenValue.html ### Polymorphism support diff --git a/manual/object_mapper/custom_codecs/README.md b/manual/object_mapper/custom_codecs/README.md index 148164ad115..d8ab8880add 100644 --- a/manual/object_mapper/custom_codecs/README.md +++ b/manual/object_mapper/custom_codecs/README.md @@ -98,9 +98,9 @@ instance (one per column) and cache it for future use. This also works with [@Field][field] and [@Param][param] annotations. -[column]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Column.html -[field]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Field.html -[param]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Param.html +[column]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Column.html +[field]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Field.html +[param]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Param.html ## Implicit UDT codecs diff --git a/manual/object_mapper/using/README.md b/manual/object_mapper/using/README.md index d802378a28a..175e3dd7d1b 100644 --- a/manual/object_mapper/using/README.md +++ b/manual/object_mapper/using/README.md @@ -28,9 +28,9 @@ Mapper mapper = manager.mapper(User.class); calling `manager#mapper` more than once for the same class will return the previously generated mapper. -[Mapper]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/Mapper.html -[MappingManager]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/MappingManager.html -[Session]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html +[Mapper]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/Mapper.html +[MappingManager]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/MappingManager.html +[Session]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html #### Basic CRUD operations @@ -179,7 +179,7 @@ It provides methods `one()`, `all()`, `iterator()`, `getExecutionInfo()` and `isExhausted()`. Note that iterating the `Result` will consume the `ResultSet`, and vice-versa. -[Result]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/Result.html +[Result]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/Result.html ### Accessors @@ -229,7 +229,7 @@ corresponds to which marker: ResultSet insert(@Param("u") UUID userId, @Param("n") String name); ``` -[param]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/Param.html +[param]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/Param.html If a method argument is a Java enumeration, it must be annotated with `@Enumerated` to indicate how to convert it to a CQL type (the rules are @@ -297,7 +297,7 @@ query with the annotation [@QueryParameters]. Then, options like public ListenableFuture> getAllAsync(); ``` -[@QueryParameters]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/annotations/QueryParameters.html +[@QueryParameters]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/annotations/QueryParameters.html ### Mapping configuration @@ -341,6 +341,6 @@ PropertyMapper propertyMapper = new DefaultPropertyMapper() There is more to `DefaultPropertyMapper`; see the Javadocs and implementation for details. -[MappingConfiguration]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/MappingConfiguration.html -[PropertyMapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/PropertyMapper.html -[DefaultPropertyMapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/mapping/DefaultPropertyMapper.html +[MappingConfiguration]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/MappingConfiguration.html +[PropertyMapper]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/PropertyMapper.html +[DefaultPropertyMapper]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/mapping/DefaultPropertyMapper.html diff --git a/manual/paging/README.md b/manual/paging/README.md index 915600d8099..0e5d8b4406e 100644 --- a/manual/paging/README.md +++ b/manual/paging/README.md @@ -176,8 +176,8 @@ if (nextPage != null) { } ``` -[result_set]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSet.html -[paging_state]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PagingState.html +[result_set]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ResultSet.html +[paging_state]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PagingState.html Due to internal implementation details, `PagingState` instances are not diff --git a/manual/pooling/README.md b/manual/pooling/README.md index f8dbd94bd27..16dc75424da 100644 --- a/manual/pooling/README.md +++ b/manual/pooling/README.md @@ -283,16 +283,16 @@ either: [newConnectionThreshold][nct] so that enough connections are added by the time you reach the bottleneck. -[result_set_future]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ResultSetFuture.html -[pooling_options]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html -[lbp]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LoadBalancingPolicy.html -[nct]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setNewConnectionThreshold-com.datastax.driver.core.HostDistance-int- -[mrpc]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setMaxRequestsPerConnection-com.datastax.driver.core.HostDistance-int- -[sits]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setIdleTimeoutSeconds-int- -[rtm]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#getReadTimeoutMillis-- -[smqs]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setMaxQueueSize-int- -[sptm]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PoolingOptions.html#setPoolTimeoutMillis-int- -[nhae]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html -[getErrors]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- -[get_state]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#getState-- -[BusyPoolException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/BusyPoolException.html +[result_set_future]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ResultSetFuture.html +[pooling_options]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html +[lbp]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/LoadBalancingPolicy.html +[nct]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html#setNewConnectionThreshold-com.datastax.driver.core.HostDistance-int- +[mrpc]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html#setMaxRequestsPerConnection-com.datastax.driver.core.HostDistance-int- +[sits]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html#setIdleTimeoutSeconds-int- +[rtm]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#getReadTimeoutMillis-- +[smqs]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html#setMaxQueueSize-int- +[sptm]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PoolingOptions.html#setPoolTimeoutMillis-int- +[nhae]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[getErrors]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- +[get_state]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#getState-- +[BusyPoolException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/BusyPoolException.html diff --git a/manual/query_timestamps/README.md b/manual/query_timestamps/README.md index cb3f4dce9cf..8f7652bbb15 100644 --- a/manual/query_timestamps/README.md +++ b/manual/query_timestamps/README.md @@ -140,10 +140,10 @@ following: Steps 2 and 3 only apply if native protocol v3 or above is in use. -[TimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TimestampGenerator.html -[AtomicMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/AtomicMonotonicTimestampGenerator.html -[ThreadLocalMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ThreadLocalMonotonicTimestampGenerator.html -[ServerSideTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ServerSideTimestampGenerator.html +[TimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/TimestampGenerator.html +[AtomicMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/AtomicMonotonicTimestampGenerator.html +[ThreadLocalMonotonicTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ThreadLocalMonotonicTimestampGenerator.html +[ServerSideTimestampGenerator]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ServerSideTimestampGenerator.html [gettimeofday]: http://man7.org/linux/man-pages/man2/settimeofday.2.html [JNR]: https://github.com/jnr/jnr-ffi diff --git a/manual/reconnection/README.md b/manual/reconnection/README.md index ccd4598a309..4cbe8e1c975 100644 --- a/manual/reconnection/README.md +++ b/manual/reconnection/README.md @@ -8,4 +8,4 @@ TODO cover: - scheduled reconnections vs. gossip events --> -[ReconnectionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/ReconnectionPolicy.html \ No newline at end of file +[ReconnectionPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/ReconnectionPolicy.html \ No newline at end of file diff --git a/manual/retries/README.md b/manual/retries/README.md index a11adb93828..f86d20fe8d0 100644 --- a/manual/retries/README.md +++ b/manual/retries/README.md @@ -146,33 +146,33 @@ implementations to handle idempotence (the new behavior is equivalent to what yo `IdempotenceAwareRetryPolicy` before). -[RetryDecision]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html -[retry()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#retry-com.datastax.driver.core.ConsistencyLevel- -[tryNextHost()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#tryNextHost-com.datastax.driver.core.ConsistencyLevel- -[rethrow()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#rethrow-- -[ignore()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#ignore-- -[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html -[getErrors()]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- -[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html -[DefaultRetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html -[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- -[onWriteTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onWriteTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.WriteType-int-int-int- -[onUnavailable]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onUnavailable-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-int- -[onRequestError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- -[UnavailableException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/UnavailableException.html -[ReadTimeoutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ReadTimeoutException.html -[WriteTimeoutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/WriteTimeoutException.html -[OverloadedException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OverloadedException.html -[ServerError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ServerError.html -[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OperationTimedOutException.html -[ConnectionException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/ConnectionException.html -[QueryValidationException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/QueryValidationException.html -[InvalidQueryException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/InvalidQueryException.html -[InvalidConfigurationInQueryException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/InvalidConfigurationInQueryException.html -[UnauthorizedException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/UnauthorizedException.html -[SyntaxError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/SyntaxError.html -[AlreadyExistsException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/AlreadyExistsException.html -[TruncateException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/TruncateException.html +[RetryDecision]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html +[retry()]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#retry-com.datastax.driver.core.ConsistencyLevel- +[tryNextHost()]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#tryNextHost-com.datastax.driver.core.ConsistencyLevel- +[rethrow()]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#rethrow-- +[ignore()]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.RetryDecision.html#ignore-- +[NoHostAvailableException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/NoHostAvailableException.html +[getErrors()]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/NoHostAvailableException.html#getErrors-- +[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.html +[DefaultRetryPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/DefaultRetryPolicy.html +[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- +[onWriteTimeout]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onWriteTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.WriteType-int-int-int- +[onUnavailable]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onUnavailable-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-int- +[onRequestError]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/DefaultRetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- +[UnavailableException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/UnavailableException.html +[ReadTimeoutException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/ReadTimeoutException.html +[WriteTimeoutException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/WriteTimeoutException.html +[OverloadedException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/OverloadedException.html +[ServerError]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/ServerError.html +[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/OperationTimedOutException.html +[ConnectionException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/ConnectionException.html +[QueryValidationException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/QueryValidationException.html +[InvalidQueryException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/InvalidQueryException.html +[InvalidConfigurationInQueryException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/InvalidConfigurationInQueryException.html +[UnauthorizedException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/UnauthorizedException.html +[SyntaxError]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/SyntaxError.html +[AlreadyExistsException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/AlreadyExistsException.html +[TruncateException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/TruncateException.html [query plan]: ../load_balancing/#query-plan [connection pool]: ../pooling/ diff --git a/manual/shaded_jar/README.md b/manual/shaded_jar/README.md index 6319c1a10fb..834d2fdc433 100644 --- a/manual/shaded_jar/README.md +++ b/manual/shaded_jar/README.md @@ -12,7 +12,7 @@ package name: com.datastax.cassandra cassandra-driver-core - 3.3.0 + 3.4.0 shaded @@ -32,7 +32,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-core - 3.3.0 + 3.4.0 shaded @@ -44,7 +44,7 @@ non-shaded JAR: com.datastax.cassandra cassandra-driver-mapping - 3.3.0 + 3.4.0 com.datastax.cassandra @@ -74,5 +74,5 @@ detects that shaded Netty classes are being used: Detected shaded Netty classes in the classpath; native epoll transport will not work properly, defaulting to NIO. -[NettyOptions]:http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/NettyOptions.html +[NettyOptions]:http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/NettyOptions.html [Netty native transports]:http://netty.io/wiki/native-transports.html diff --git a/manual/socket_options/README.md b/manual/socket_options/README.md index 8a0defd87e7..e822d20854c 100644 --- a/manual/socket_options/README.md +++ b/manual/socket_options/README.md @@ -117,15 +117,15 @@ To clarify: We might rename `SocketOptions.setReadTimeoutMillis` in a future version to clear up any confusion. -[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html -[setReadTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReadTimeoutMillis-int- -[setConnectTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setConnectTimeoutMillis-int- -[setKeepAlive]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setKeepAlive-boolean- -[setReceiveBufferSize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReceiveBufferSize-int- -[setReuseAddress]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setReuseAddress-boolean- -[setSendBufferSize]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setSendBufferSize-int- -[setSoLinger]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setSoLinger-int- -[setTcpNoDelay]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SocketOptions.html#setTcpNoDelay-boolean- -[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- -[onRequestError]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- -[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/exceptions/OperationTimedOutException.html \ No newline at end of file +[SocketOptions]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html +[setReadTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setReadTimeoutMillis-int- +[setConnectTimeoutMillis]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setConnectTimeoutMillis-int- +[setKeepAlive]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setKeepAlive-boolean- +[setReceiveBufferSize]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setReceiveBufferSize-int- +[setReuseAddress]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setReuseAddress-boolean- +[setSendBufferSize]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setSendBufferSize-int- +[setSoLinger]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setSoLinger-int- +[setTcpNoDelay]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SocketOptions.html#setTcpNoDelay-boolean- +[onReadTimeout]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.html#onReadTimeout-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-int-int-boolean-int- +[onRequestError]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.html#onRequestError-com.datastax.driver.core.Statement-com.datastax.driver.core.ConsistencyLevel-com.datastax.driver.core.exceptions.DriverException-int- +[OperationTimedOutException]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/exceptions/OperationTimedOutException.html \ No newline at end of file diff --git a/manual/speculative_execution/README.md b/manual/speculative_execution/README.md index ceecc2a0f3b..38af43c2d7f 100644 --- a/manual/speculative_execution/README.md +++ b/manual/speculative_execution/README.md @@ -73,7 +73,7 @@ Speculative executions are controlled by an instance of `Cluster`. This policy defines the threshold after which a new speculative execution will be triggered. -[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html +[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html Two implementations are provided with the driver: @@ -101,7 +101,7 @@ way: * if no response has been received at t0 + 1000 milliseconds, start another speculative execution on a third node. -[ConstantSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.html +[ConstantSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/ConstantSpeculativeExecutionPolicy.html #### [PercentileSpeculativeExecutionPolicy] @@ -160,10 +160,10 @@ Note that `PercentileTracker` may also be used with a slow query logger (see the [Logging](../logging/) section). In that case, you would create a single tracker object and share it with both components. -[PercentileSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/PercentileSpeculativeExecutionPolicy.html -[PercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PercentileTracker.html -[ClusterWidePercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ClusterWidePercentileTracker.html -[PerHostPercentileTracker]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PerHostPercentileTracker.html +[PercentileSpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/PercentileSpeculativeExecutionPolicy.html +[PercentileTracker]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PercentileTracker.html +[ClusterWidePercentileTracker]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ClusterWidePercentileTracker.html +[PerHostPercentileTracker]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PerHostPercentileTracker.html [hdr]: http://hdrhistogram.github.io/HdrHistogram/ #### Using your own @@ -210,7 +210,7 @@ client driver exec1 exec2 The only impact is that all executions of the same query always share the same query plan, so each host will be used by at most one execution. -[retry_policy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html +[retry_policy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.html ### Tuning and practical details @@ -225,8 +225,8 @@ You can monitor how many speculative executions were triggered with the It should only be a few percents of the total number of requests ([cluster.getMetrics().getRequestsTimer().getCount()][request_metric]). -[se_metric]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.Errors.html#getSpeculativeExecutions-- -[request_metric]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Metrics.html#getRequestsTimer-- +[se_metric]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Metrics.Errors.html#getSpeculativeExecutions-- +[request_metric]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Metrics.html#getRequestsTimer-- #### Stream id exhaustion @@ -255,8 +255,8 @@ sustained. If you're unsure of which native protocol version you're using, you can check with [cluster.getConfiguration().getProtocolOptions().getProtocolVersion()][protocol_version]. -[session_state]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.State.html -[protocol_version]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- +[session_state]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.State.html +[protocol_version]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/ProtocolOptions.html#getProtocolVersion-- #### Request ordering and client timestamps diff --git a/manual/ssl/README.md b/manual/ssl/README.md index 59249b586c2..1e8244d037e 100644 --- a/manual/ssl/README.md +++ b/manual/ssl/README.md @@ -185,8 +185,8 @@ Cluster cluster = Cluster.builder() .build(); ``` -[RemoteEndpointAwareSSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareSSLOptions.html -[RemoteEndpointAwareJdkSSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html -[newSSLEngine]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html#newSSLEngine-io.netty.channel.socket.SocketChannel-java.net.InetSocketAddress- -[RemoteEndpointAwareNettySSLOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/RemoteEndpointAwareNettySSLOptions.html -[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/NettyOptions.html +[RemoteEndpointAwareSSLOptions]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/RemoteEndpointAwareSSLOptions.html +[RemoteEndpointAwareJdkSSLOptions]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html +[newSSLEngine]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/RemoteEndpointAwareJdkSSLOptions.html#newSSLEngine-io.netty.channel.socket.SocketChannel-java.net.InetSocketAddress- +[RemoteEndpointAwareNettySSLOptions]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/RemoteEndpointAwareNettySSLOptions.html +[NettyOptions]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/NettyOptions.html diff --git a/manual/statements/README.md b/manual/statements/README.md index 6efd14ce104..4e687abfc06 100644 --- a/manual/statements/README.md +++ b/manual/statements/README.md @@ -32,11 +32,11 @@ If you use custom policies ([RetryPolicy], [LoadBalancingPolicy], properties that influence statement execution. To achieve this, you can wrap your statements in a custom [StatementWrapper] implementation. -[Statement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Statement.html -[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/QueryBuilder.html -[StatementWrapper]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/StatementWrapper.html -[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/RetryPolicy.html -[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/LoadBalancingPolicy.html -[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html -[execute]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- -[executeAsync]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- +[Statement]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Statement.html +[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/querybuilder/QueryBuilder.html +[StatementWrapper]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/StatementWrapper.html +[RetryPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/RetryPolicy.html +[LoadBalancingPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/LoadBalancingPolicy.html +[SpeculativeExecutionPolicy]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/policies/SpeculativeExecutionPolicy.html +[execute]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- +[executeAsync]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- diff --git a/manual/statements/batch/README.md b/manual/statements/batch/README.md index 5f3b7930c32..42ad8ccb3c0 100644 --- a/manual/statements/batch/README.md +++ b/manual/statements/batch/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [BatchStatement].* -[BatchStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BatchStatement.html +[BatchStatement]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/BatchStatement.html diff --git a/manual/statements/built/README.md b/manual/statements/built/README.md index 405aa9d2161..a54ea218089 100644 --- a/manual/statements/built/README.md +++ b/manual/statements/built/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [QueryBuilder].* -[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/querybuilder/QueryBuilder.html \ No newline at end of file +[QueryBuilder]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/querybuilder/QueryBuilder.html \ No newline at end of file diff --git a/manual/statements/prepared/README.md b/manual/statements/prepared/README.md index e6d351d07a8..8f255790c8c 100644 --- a/manual/statements/prepared/README.md +++ b/manual/statements/prepared/README.md @@ -256,11 +256,11 @@ relying on `SELECT *`. This will be addressed in a future release of both Cassandra and the driver. Follow [CASSANDRA-10786] and [JAVA-1196] for more information. -[PreparedStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/PreparedStatement.html -[BoundStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/BoundStatement.html -[setPrepareOnAllHosts]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setPrepareOnAllHosts-boolean- -[setReprepareOnUp]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/QueryOptions.html#setReprepareOnUp-boolean- -[execute]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- -[executeAsync]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- +[PreparedStatement]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/PreparedStatement.html +[BoundStatement]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/BoundStatement.html +[setPrepareOnAllHosts]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/QueryOptions.html#setPrepareOnAllHosts-boolean- +[setReprepareOnUp]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/QueryOptions.html#setReprepareOnUp-boolean- +[execute]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#execute-com.datastax.driver.core.Statement- +[executeAsync]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Session.html#executeAsync-com.datastax.driver.core.Statement- [CASSANDRA-10786]: https://issues.apache.org/jira/browse/CASSANDRA-10786 [JAVA-1196]: https://datastax-oss.atlassian.net/browse/JAVA-1196 diff --git a/manual/statements/simple/README.md b/manual/statements/simple/README.md index 9967b0e4bf3..7740d40b42f 100644 --- a/manual/statements/simple/README.md +++ b/manual/statements/simple/README.md @@ -128,4 +128,4 @@ session.execute( 1, bytes); ``` -[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/SimpleStatement.html +[SimpleStatement]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/SimpleStatement.html diff --git a/manual/tuples/README.md b/manual/tuples/README.md index 345bcc517ff..276d3ff2dc9 100644 --- a/manual/tuples/README.md +++ b/manual/tuples/README.md @@ -96,7 +96,7 @@ bs.setList("l", Arrays.asList(oneTimeUsageTuple.newValue("1", "1"), oneTimeUsage session.execute(bs); ``` -[TupleType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html -[TupleValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleValue.html -[newValueVararg]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html#newValue-java.lang.Object...- -[newValue]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/TupleType.html#newValue-- +[TupleType]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/TupleType.html +[TupleValue]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/TupleValue.html +[newValueVararg]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/TupleType.html#newValue-java.lang.Object...- +[newValue]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/TupleType.html#newValue-- diff --git a/manual/udts/README.md b/manual/udts/README.md index 760b87e9321..478c919c691 100644 --- a/manual/udts/README.md +++ b/manual/udts/README.md @@ -2,4 +2,4 @@ *Coming soon... In the meantime, see the javadoc for [UserType].* -[UserType]: http://docs.datastax.com/en/drivers/java/3.2/com/datastax/driver/core/UserType.html \ No newline at end of file +[UserType]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/UserType.html \ No newline at end of file diff --git a/pom.xml b/pom.xml index 61bca0bf56c..bbeb75bdb53 100644 --- a/pom.xml +++ b/pom.xml @@ -631,7 +631,7 @@ - 3.3.0 + 3.3.2 ../clirr-ignores.xml com/datastax/shaded/** From 2eba90ec83d20149a4160c6a45ea86917e0e3545 Mon Sep 17 00:00:00 2001 From: olim7t Date: Thu, 18 Jan 2018 14:12:25 -0800 Subject: [PATCH 064/382] [maven-release-plugin] prepare release 3.4.0 --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 173c1f244f6..0e66fd1ce39 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index bf96c3bae87..d8a1efed7bf 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index 6c3f858195b..b162e279ef0 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 0ef852735ac..84d63c7d6d0 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index da78cb6db2e..5b79bd71fbe 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index 04d181035f2..6d1b2d120b4 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index 6b2adbf3f4c..d5bc9157dac 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index 9f089fa7e03..a0a431284d2 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.4.0 pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index f943aa80c2a..e8fc3ad554d 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index 11188fa9574..d8edd06498e 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index e6940e2e52e..e3fb66c90cb 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0-SNAPSHOT + 3.4.0 cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index bbeb75bdb53..735005db35e 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0-SNAPSHOT + 3.4.0 pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - HEAD + 3.4.0 From c73e5a288f564c4c410a4ac2b34c597bb86b0813 Mon Sep 17 00:00:00 2001 From: olim7t Date: Thu, 18 Jan 2018 14:12:35 -0800 Subject: [PATCH 065/382] [maven-release-plugin] prepare for next development iteration --- driver-core/pom.xml | 2 +- driver-dist/pom.xml | 2 +- driver-examples/pom.xml | 2 +- driver-extras/pom.xml | 2 +- driver-mapping/pom.xml | 2 +- driver-tests/osgi/pom.xml | 2 +- driver-tests/pom.xml | 2 +- driver-tests/shading/pom.xml | 2 +- driver-tests/shading/shaded/pom.xml | 2 +- driver-tests/shading/unshaded/pom.xml | 2 +- driver-tests/stress/pom.xml | 2 +- pom.xml | 4 ++-- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/driver-core/pom.xml b/driver-core/pom.xml index 0e66fd1ce39..b38c8338152 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-core diff --git a/driver-dist/pom.xml b/driver-dist/pom.xml index d8a1efed7bf..358ab1e6907 100644 --- a/driver-dist/pom.xml +++ b/driver-dist/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-dist diff --git a/driver-examples/pom.xml b/driver-examples/pom.xml index b162e279ef0..3f6338ce082 100644 --- a/driver-examples/pom.xml +++ b/driver-examples/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-examples diff --git a/driver-extras/pom.xml b/driver-extras/pom.xml index 84d63c7d6d0..2c969a60b13 100644 --- a/driver-extras/pom.xml +++ b/driver-extras/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-extras diff --git a/driver-mapping/pom.xml b/driver-mapping/pom.xml index 5b79bd71fbe..8ba0dbb51af 100644 --- a/driver-mapping/pom.xml +++ b/driver-mapping/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-mapping diff --git a/driver-tests/osgi/pom.xml b/driver-tests/osgi/pom.xml index 6d1b2d120b4..b2b6a3b3735 100644 --- a/driver-tests/osgi/pom.xml +++ b/driver-tests/osgi/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-tests-osgi diff --git a/driver-tests/pom.xml b/driver-tests/pom.xml index d5bc9157dac..8aeb2da4cca 100644 --- a/driver-tests/pom.xml +++ b/driver-tests/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-tests-parent diff --git a/driver-tests/shading/pom.xml b/driver-tests/shading/pom.xml index a0a431284d2..36325c83651 100644 --- a/driver-tests/shading/pom.xml +++ b/driver-tests/shading/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0 + 3.4.1-SNAPSHOT pom diff --git a/driver-tests/shading/shaded/pom.xml b/driver-tests/shading/shaded/pom.xml index e8fc3ad554d..033a679fc55 100644 --- a/driver-tests/shading/shaded/pom.xml +++ b/driver-tests/shading/shaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-tests-shading-shaded diff --git a/driver-tests/shading/unshaded/pom.xml b/driver-tests/shading/unshaded/pom.xml index d8edd06498e..c0765ca9ec4 100644 --- a/driver-tests/shading/unshaded/pom.xml +++ b/driver-tests/shading/unshaded/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-shading - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-tests-shading-unshaded diff --git a/driver-tests/stress/pom.xml b/driver-tests/stress/pom.xml index e3fb66c90cb..e6c09cac0c8 100644 --- a/driver-tests/stress/pom.xml +++ b/driver-tests/stress/pom.xml @@ -22,7 +22,7 @@ com.datastax.cassandra cassandra-driver-tests-parent - 3.4.0 + 3.4.1-SNAPSHOT cassandra-driver-tests-stress diff --git a/pom.xml b/pom.xml index 735005db35e..3f4c5c92a98 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.datastax.cassandra cassandra-driver-parent - 3.4.0 + 3.4.1-SNAPSHOT pom DataStax Java Driver for Apache Cassandra @@ -1076,7 +1076,7 @@ limitations under the License. scm:git:git@github.com:datastax/java-driver.git scm:git:git@github.com:datastax/java-driver.git https://github.com/datastax/java-driver - 3.4.0 + HEAD From 57724bd63c3038e3728260c7640abcea06f33b86 Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Tue, 23 Jan 2018 22:33:26 -0600 Subject: [PATCH 066/382] Skip tests that require COMPACT STORAGE if C* >= 4.0 --- .../datastax/driver/core/CustomTypeTest.java | 37 ++++++++++++------- .../driver/core/TableMetadataTest.java | 4 ++ .../com/datastax/driver/core/TestUtils.java | 11 ++++++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/driver-core/src/test/java/com/datastax/driver/core/CustomTypeTest.java b/driver-core/src/test/java/com/datastax/driver/core/CustomTypeTest.java index ea1e466c1cc..91535ce6625 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CustomTypeTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CustomTypeTest.java @@ -16,6 +16,7 @@ package com.datastax.driver.core; import com.datastax.driver.core.utils.CassandraVersion; +import org.testng.SkipException; import org.testng.annotations.Test; import java.nio.ByteBuffer; @@ -45,20 +46,25 @@ public class CustomTypeTest extends CCMTestsSupport { @Override public void onTestContextInitialized() { - execute( - "CREATE TABLE test (" - + " k int," - + " c1 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'," - + " c2 'ReversedType(CompositeType(UTF8Type, Int32Type))'," // reversed translates to CLUSTERING ORDER BY DESC - + " c3 'Int32Type'," // translates to int - + " PRIMARY KEY (k, c1, c2)" - + ") WITH COMPACT STORAGE", - "CREATE TABLE test_collection(" - + " k int PRIMARY KEY," - + " c1 list<'DynamicCompositeType(s => UTF8Type, i => Int32Type)'>," - + " c2 map<'DynamicCompositeType(s => UTF8Type, i => Int32Type)', 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'>" - + ")" - ); + try { + TestUtils.compactStorageSupportCheck(ccm()); + execute( + "CREATE TABLE test (" + + " k int," + + " c1 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'," + + " c2 'ReversedType(CompositeType(UTF8Type, Int32Type))'," // reversed translates to CLUSTERING ORDER BY DESC + + " c3 'Int32Type'," // translates to int + + " PRIMARY KEY (k, c1, c2)" + + ") WITH COMPACT STORAGE", + "CREATE TABLE test_collection(" + + " k int PRIMARY KEY," + + " c1 list<'DynamicCompositeType(s => UTF8Type, i => Int32Type)'>," + + " c2 map<'DynamicCompositeType(s => UTF8Type, i => Int32Type)', 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'>" + + ")" + ); + } catch (SkipException e) { + // no op, tests will be skipped. + } } /** @@ -75,6 +81,7 @@ public void onTestContextInitialized() { */ @Test(groups = "short") public void should_serialize_and_deserialize_custom_types() { + TestUtils.compactStorageSupportCheck(ccm()); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("test"); @@ -120,6 +127,7 @@ public void should_serialize_and_deserialize_custom_types() { */ @Test(groups = "short") public void should_serialize_and_deserialize_collections_of_custom_types() { + TestUtils.compactStorageSupportCheck(ccm()); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("test_collection"); assertThat(table.getColumn("c1")).hasType(DataType.list(CUSTOM_DYNAMIC_COMPOSITE)); assertThat(table.getColumn("c2")).hasType(DataType.map(CUSTOM_DYNAMIC_COMPOSITE, CUSTOM_DYNAMIC_COMPOSITE)); @@ -154,6 +162,7 @@ public void should_serialize_and_deserialize_collections_of_custom_types() { @Test(groups = "short") @CassandraVersion("2.1.0") public void should_handle_udt_with_custom_type() { + TestUtils.compactStorageSupportCheck(ccm()); // Given: a UDT with custom types, and a table using it. session().execute("CREATE TYPE custom_udt (regular int, c1 'DynamicCompositeType(s => UTF8Type, i => Int32Type)', c2 'LongType')"); session().execute("CREATE TABLE custom_udt_tbl (k int primary key, v frozen)"); diff --git a/driver-core/src/test/java/com/datastax/driver/core/TableMetadataTest.java b/driver-core/src/test/java/com/datastax/driver/core/TableMetadataTest.java index 58ddf2abdb9..5ded7a07c73 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/TableMetadataTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/TableMetadataTest.java @@ -93,6 +93,7 @@ public void should_parse_counter_table() { @Test(groups = "short") public void should_parse_compact_static_table() { + TestUtils.compactStorageSupportCheck(ccm()); // given String cql = String.format("CREATE TABLE %s.compact_static (\n" + " k text,\n" @@ -114,6 +115,7 @@ public void should_parse_compact_static_table() { @Test(groups = "short") public void should_parse_dense_table() { + TestUtils.compactStorageSupportCheck(ccm()); // given String cql = String.format("CREATE TABLE %s.dense (\n" + " k int,\n" @@ -131,6 +133,7 @@ public void should_parse_dense_table() { @Test(groups = "short") public void should_parse_compact_dynamic_table() { + TestUtils.compactStorageSupportCheck(ccm()); // given String cql = String.format("CREATE TABLE %s.compact_dynamic (\n" + " k text,\n" @@ -150,6 +153,7 @@ public void should_parse_compact_dynamic_table() { @Test(groups = "short") public void should_parse_compact_table_with_multiple_clustering_columns() { + TestUtils.compactStorageSupportCheck(ccm()); // given String cql = String.format("CREATE TABLE %s.compact_composite (\n" + " k text,\n" diff --git a/driver-core/src/test/java/com/datastax/driver/core/TestUtils.java b/driver-core/src/test/java/com/datastax/driver/core/TestUtils.java index 1b4916b679b..76795e43288 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/TestUtils.java +++ b/driver-core/src/test/java/com/datastax/driver/core/TestUtils.java @@ -39,6 +39,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; +import org.testng.SkipException; import static com.datastax.driver.core.ConditionChecker.check; import static java.util.concurrent.TimeUnit.MINUTES; @@ -932,4 +933,14 @@ public static Level setLogLevel(String logger, Level newLevel) { return oldLevel; } + /** + * Throws a {@link SkipException} if the input {@link CCMAccess} does not support compact storage (C* 4.0+) + * @param ccm cluster to check against + */ + public static void compactStorageSupportCheck(CCMAccess ccm) { + if (ccm.getCassandraVersion().compareTo(VersionNumber.parse("4.0.0")) >= 0) { + throw new SkipException("Compact tables are not allowed in Cassandra starting with 4.0 version"); + } + } + } From 9a8a23fdc5e60f12a719ac490e6ec2fc001b1b4a Mon Sep 17 00:00:00 2001 From: Alexandre Dutra Date: Wed, 28 Feb 2018 14:42:55 +0100 Subject: [PATCH 067/382] JAVA-1448: TokenAwarePolicy should respect child policy ordering (#956) --- changelog/README.md | 5 + .../core/policies/TokenAwarePolicy.java | 221 ++++++++++---- .../core/policies/TokenAwarePolicyTest.java | 277 +++++++++++------- upgrade_guide/README.md | 14 + 4 files changed, 349 insertions(+), 168 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 8b0c2e215a5..76e180e70f7 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,5 +1,10 @@ ## Changelog +### 3.5.0 (in progress) + +- [improvement] JAVA-1448: TokenAwarePolicy should respect child policy ordering. + + ### 3.4.0 - [improvement] JAVA-1671: Remove unnecessary test on prepared statement metadata. diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/TokenAwarePolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/TokenAwarePolicy.java index ce3ce756f9c..5e97afb27e3 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/TokenAwarePolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/TokenAwarePolicy.java @@ -23,31 +23,70 @@ import java.util.*; /** - * A wrapper load balancing policy that add token awareness to a child policy. + * A wrapper load balancing policy that adds token awareness to a child policy. *

* This policy encapsulates another policy. The resulting policy works in * the following way: *

    *
  • the {@code distance} method is inherited from the child policy.
  • - *
  • the iterator return by the {@code newQueryPlan} method will first - * return the {@code LOCAL} replicas for the query (based on {@link Statement#getRoutingKey}) - * if possible (i.e. if the query {@code getRoutingKey} method - * doesn't return {@code null} and if {@link Metadata#getReplicas} - * returns a non empty set of replicas for that partition key). If no - * local replica can be either found or successfully contacted, the rest - * of the query plan will fallback to one of the child policy.
  • + *
  • the iterator returned by the {@code newQueryPlan} method will first + * return the {@link HostDistance#LOCAL LOCAL} replicas for the query + * if possible (i.e. if the query's + * {@linkplain Statement#getRoutingKey(ProtocolVersion, CodecRegistry) routing key} + * is not {@code null} and if the + * {@linkplain Metadata#getReplicas(String, ByteBuffer) set of replicas} + * for that partition key is not empty). If no local replica can be either found + * or successfully contacted, the rest of the query plan will fallback + * to the child policy's one.
  • *
+ * The exact order in which local replicas are returned is dictated by the + * {@linkplain ReplicaOrdering strategy} provided at instantiation. *

- * Do note that only replica for which the child policy {@code distance} - * method returns {@code HostDistance.LOCAL} will be considered having + * Do note that only replicas for which the child policy's + * {@linkplain LoadBalancingPolicy#distance(Host) distance} + * method returns {@link HostDistance#LOCAL LOCAL} will be considered having * priority. For example, if you wrap {@link DCAwareRoundRobinPolicy} with this * token aware policy, replicas from remote data centers may only be - * returned after all the host of the local data center. + * returned after all the hosts of the local data center. */ public class TokenAwarePolicy implements ChainableLoadBalancingPolicy { + /** + * Strategies for replica ordering. + */ + public enum ReplicaOrdering { + + /** + * Order replicas by token ring topology, i.e. always return the "primary" replica first, + * then the second, etc., according to the placement of replicas around the token ring. + *

+ * This strategy is the only one guaranteed to order replicas in a deterministic and + * constant way. This increases the effectiveness of server-side row caching (especially + * at consistency level ONE), but is more heavily impacted by hotspots, since the primary + * replica is always tried first. + */ + TOPOLOGICAL, + + /** + * Return replicas in a different, random order for each query plan. This is the default strategy. + *

+ * This strategy fans out writes and thus can alleviate hotspots caused by "fat" partitions, + * but its randomness makes server-side caching less efficient. + */ + RANDOM, + + /** + * Return the replicas in the exact same order in which they appear in the child + * policy's query plan. + *

+ * This is the only strategy that fully respects the child policy's replica ordering. + * Use it when it is important to keep that order intact (e.g. when using the {@link LatencyAwarePolicy}). + */ + NEUTRAL + } + private final LoadBalancingPolicy childPolicy; - private final boolean shuffleReplicas; + private final ReplicaOrdering replicaOrdering; private volatile Metadata clusterMetadata; private volatile ProtocolVersion protocolVersion; private volatile CodecRegistry codecRegistry; @@ -56,28 +95,36 @@ public class TokenAwarePolicy implements ChainableLoadBalancingPolicy { * Creates a new {@code TokenAware} policy. * * @param childPolicy the load balancing policy to wrap with token awareness. - * @param shuffleReplicas whether to shuffle the replicas returned by {@code getRoutingKey}. - * Note that setting this parameter to {@code true} might decrease the - * effectiveness of caching (especially at consistency level ONE), since - * the same row will be retrieved from any replica (instead of only the - * "primary" replica without shuffling). - * On the other hand, shuffling will better distribute writes, and can - * alleviate hotspots caused by "fat" partitions. + * @param replicaOrdering the strategy to use to order replicas. */ - public TokenAwarePolicy(LoadBalancingPolicy childPolicy, boolean shuffleReplicas) { + public TokenAwarePolicy(LoadBalancingPolicy childPolicy, ReplicaOrdering replicaOrdering) { this.childPolicy = childPolicy; - this.shuffleReplicas = shuffleReplicas; + this.replicaOrdering = replicaOrdering; } /** - * Creates a new {@code TokenAware} policy with shuffling of replicas. + * Creates a new {@code TokenAware} policy. * - * @param childPolicy the load balancing policy to wrap with token - * awareness. - * @see #TokenAwarePolicy(LoadBalancingPolicy, boolean) + * @param childPolicy the load balancing policy to wrap with token awareness. + * @param shuffleReplicas whether or not to shuffle the replicas. + * If {@code true}, then the {@link ReplicaOrdering#RANDOM RANDOM} strategy will be used, + * otherwise the {@link ReplicaOrdering#TOPOLOGICAL TOPOLOGICAL} one will be used. + * @deprecated Use {@link #TokenAwarePolicy(LoadBalancingPolicy, ReplicaOrdering)} instead. + * This constructor will be removed in the next major release. + */ + @SuppressWarnings("DeprecatedIsStillUsed") + @Deprecated + public TokenAwarePolicy(LoadBalancingPolicy childPolicy, boolean shuffleReplicas) { + this(childPolicy, shuffleReplicas ? ReplicaOrdering.RANDOM : ReplicaOrdering.TOPOLOGICAL); + } + + /** + * Creates a new {@code TokenAware} policy with {@link ReplicaOrdering#RANDOM RANDOM} replica ordering. + * + * @param childPolicy the load balancing policy to wrap with token awareness. */ public TokenAwarePolicy(LoadBalancingPolicy childPolicy) { - this(childPolicy, true); + this(childPolicy, ReplicaOrdering.RANDOM); } @Override @@ -94,10 +141,9 @@ public void init(Cluster cluster, Collection hosts) { } /** - * Return the HostDistance for the provided host. - * - * @param host the host of which to return the distance of. - * @return the HostDistance to {@code host} as returned by the wrapped policy. + * {@inheritDoc} + *

+ * This implementation always returns distances as reported by the wrapped policy. */ @Override public HostDistance distance(Host host) { @@ -105,15 +151,15 @@ public HostDistance distance(Host host) { } /** - * Returns the hosts to use for a new query. + * {@inheritDoc} *

- * The returned plan will first return replicas (whose {@code HostDistance} - * for the child policy is {@code LOCAL}) for the query if it can determine - * them (i.e. mainly if {@code statement.getRoutingKey()} is not {@code null}). - * Following what it will return the plan of the child policy. - * - * @param statement the query for which to build the plan. - * @return the new query plan. + * The returned plan will first return local replicas for the query (i.e. + * replicas whose {@linkplain HostDistance distance} according to the child policy is {@code LOCAL}), + * if it can determine them (i.e. mainly if the statement's + * {@linkplain Statement#getRoutingKey(ProtocolVersion, CodecRegistry) routing key} + * is not {@code null}), and ordered according to the {@linkplain ReplicaOrdering ordering strategy} + * specified at instantiation; following what it will return the rest of the child policy's + * original query plan. */ @Override public Iterator newQueryPlan(final String loggedKeyspace, final Statement statement) { @@ -130,39 +176,86 @@ public Iterator newQueryPlan(final String loggedKeyspace, final Statement if (replicas.isEmpty()) return childPolicy.newQueryPlan(loggedKeyspace, statement); - final Iterator iter; - if (shuffleReplicas) { - List l = Lists.newArrayList(replicas); - Collections.shuffle(l); - iter = l.iterator(); - } else { - iter = replicas.iterator(); - } + if (replicaOrdering == ReplicaOrdering.NEUTRAL) { - return new AbstractIterator() { + final Iterator childIterator = childPolicy.newQueryPlan(keyspace, statement); - private Iterator childIterator; + return new AbstractIterator() { - @Override - protected Host computeNext() { - while (iter.hasNext()) { - Host host = iter.next(); - if (host.isUp() && childPolicy.distance(host) == HostDistance.LOCAL) - return host; - } + private List nonReplicas; + private Iterator nonReplicasIterator; + + @Override + protected Host computeNext() { + + while (childIterator.hasNext()) { + + Host host = childIterator.next(); + + if (host.isUp() && replicas.contains(host) && childPolicy.distance(host) == HostDistance.LOCAL) { + // UP replicas should be prioritized, retaining order from childPolicy + return host; + } else { + // save for later + if (nonReplicas == null) + nonReplicas = new ArrayList(); + nonReplicas.add(host); + } - if (childIterator == null) - childIterator = childPolicy.newQueryPlan(loggedKeyspace, statement); + } - while (childIterator.hasNext()) { - Host host = childIterator.next(); - // Skip it if it was already a local replica - if (!replicas.contains(host) || childPolicy.distance(host) != HostDistance.LOCAL) - return host; + // This should only engage if all local replicas are DOWN + if (nonReplicas != null) { + + if (nonReplicasIterator == null) + nonReplicasIterator = nonReplicas.iterator(); + + if (nonReplicasIterator.hasNext()) + return nonReplicasIterator.next(); + } + + return endOfData(); } - return endOfData(); + }; + + } else { + + final Iterator replicasIterator; + + if (replicaOrdering == ReplicaOrdering.RANDOM) { + List replicasList = Lists.newArrayList(replicas); + Collections.shuffle(replicasList); + replicasIterator = replicasList.iterator(); + } else { + replicasIterator = replicas.iterator(); } - }; + + return new AbstractIterator() { + + private Iterator childIterator; + + @Override + protected Host computeNext() { + while (replicasIterator.hasNext()) { + Host host = replicasIterator.next(); + if (host.isUp() && childPolicy.distance(host) == HostDistance.LOCAL) + return host; + } + + if (childIterator == null) + childIterator = childPolicy.newQueryPlan(loggedKeyspace, statement); + + while (childIterator.hasNext()) { + Host host = childIterator.next(); + // Skip it if it was already a local replica + if (!replicas.contains(host) || childPolicy.distance(host) != HostDistance.LOCAL) + return host; + } + return endOfData(); + } + }; + } + } @Override diff --git a/driver-core/src/test/java/com/datastax/driver/core/policies/TokenAwarePolicyTest.java b/driver-core/src/test/java/com/datastax/driver/core/policies/TokenAwarePolicyTest.java index 1464187ba41..d3ca3912425 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/policies/TokenAwarePolicyTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/policies/TokenAwarePolicyTest.java @@ -18,38 +18,105 @@ import com.datastax.driver.core.*; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import java.nio.ByteBuffer; +import java.util.Iterator; +import java.util.List; +import org.assertj.core.util.Sets; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.nio.ByteBuffer; -import java.util.List; - import static com.datastax.driver.core.Assertions.assertThat; -import static com.datastax.driver.core.CreateCCM.TestMode.PER_METHOD; import static com.datastax.driver.core.TestUtils.CREATE_KEYSPACE_SIMPLE_FORMAT; import static com.datastax.driver.core.TestUtils.nonQuietClusterCloseOptions; - -@CreateCCM(PER_METHOD) -@CCMConfig(createCcm = false) -public class TokenAwarePolicyTest extends CCMTestsSupport { - - QueryTracker queryTracker; - - @BeforeMethod(groups = "short") - public void setUp() { - queryTracker = new QueryTracker(); +import static com.datastax.driver.core.policies.TokenAwarePolicy.ReplicaOrdering.NEUTRAL; +import static com.datastax.driver.core.policies.TokenAwarePolicy.ReplicaOrdering.RANDOM; +import static com.datastax.driver.core.policies.TokenAwarePolicy.ReplicaOrdering.TOPOLOGICAL; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class TokenAwarePolicyTest { + + private ByteBuffer routingKey = ByteBuffer.wrap(new byte[]{1, 2, 3, 4}); + + private RegularStatement statement = new SimpleStatement("irrelevant") + .setRoutingKey(routingKey); + + private Host host1 = mock(Host.class); + private Host host2 = mock(Host.class); + private Host host3 = mock(Host.class); + private Host host4 = mock(Host.class); + + private LoadBalancingPolicy childPolicy; + private Cluster cluster; + + @BeforeMethod(groups = "unit") + public void initMocks() { + CodecRegistry codecRegistry = new CodecRegistry(); + cluster = mock(Cluster.class); + Configuration configuration = mock(Configuration.class); + ProtocolOptions protocolOptions = mock(ProtocolOptions.class); + Metadata metadata = mock(Metadata.class); + childPolicy = mock(LoadBalancingPolicy.class); + when(cluster.getConfiguration()).thenReturn(configuration); + when(configuration.getCodecRegistry()).thenReturn(codecRegistry); + when(configuration.getProtocolOptions()).thenReturn(protocolOptions); + when(protocolOptions.getProtocolVersion()).thenReturn(ProtocolVersion.NEWEST_SUPPORTED); + when(cluster.getMetadata()).thenReturn(metadata); + when(metadata.getReplicas(Metadata.quote("keyspace"), routingKey)) + .thenReturn(Sets.newLinkedHashSet(host1, host2)); + when(childPolicy.newQueryPlan("keyspace", statement)).thenReturn( + Sets.newLinkedHashSet(host4, host3, host2, host1).iterator()); + when(childPolicy.distance(any(Host.class))).thenReturn(HostDistance.LOCAL); + when(host1.isUp()).thenReturn(true); + when(host2.isUp()).thenReturn(true); + when(host3.isUp()).thenReturn(true); + when(host4.isUp()).thenReturn(true); } @DataProvider(name = "shuffleProvider") public Object[][] shuffleProvider() { return new Object[][]{ - {true}, - {false}, - {null} + {TokenAwarePolicy.ReplicaOrdering.TOPOLOGICAL}, + {TokenAwarePolicy.ReplicaOrdering.RANDOM}, + {TokenAwarePolicy.ReplicaOrdering.NEUTRAL} }; } + @Test(groups = "unit") + public void should_respect_topological_order() { + // given + TokenAwarePolicy policy = new TokenAwarePolicy(childPolicy, TOPOLOGICAL); + policy.init(cluster, null); + // when + Iterator queryPlan = policy.newQueryPlan("keyspace", statement); + // then + assertThat(queryPlan).containsExactly(host1, host2, host4, host3); + } + + @Test(groups = "unit") + public void should_respect_child_policy_order() { + // given + TokenAwarePolicy policy = new TokenAwarePolicy(childPolicy, NEUTRAL); + policy.init(cluster, null); + // when + Iterator queryPlan = policy.newQueryPlan("keyspace", statement); + // then + assertThat(queryPlan).containsExactly(host2, host1, host4, host3); + } + + @Test(groups = "unit") + public void should_create_random_order() { + // given + TokenAwarePolicy policy = new TokenAwarePolicy(childPolicy, RANDOM); + policy.init(cluster, null); + // when + Iterator queryPlan = policy.newQueryPlan("keyspace", statement); + // then + assertThat(queryPlan).containsOnlyOnce(host1, host2, host3, host4).endsWith(host4, host3); + } + /** * Ensures that {@link TokenAwarePolicy} will shuffle discovered replicas depending on the value of shuffleReplicas * used when constructing with {@link TokenAwarePolicy#TokenAwarePolicy(LoadBalancingPolicy, boolean)} and that if not @@ -58,20 +125,14 @@ public Object[][] shuffleProvider() { * @test_category load_balancing:token_aware */ @Test(groups = "short", dataProvider = "shuffleProvider") - public void should_shuffle_replicas_based_on_configuration(Boolean shuffleReplicas) { + public void should_order_replicas_based_on_configuration(TokenAwarePolicy.ReplicaOrdering ordering) { // given: an 8 node cluster using TokenAwarePolicy and some shuffle replica configuration with a keyspace with replication factor of 3. ScassandraCluster sCluster = ScassandraCluster.builder() .withNodes(8) .withSimpleKeyspace("keyspace", 3) .build(); - LoadBalancingPolicy loadBalancingPolicy; - if (shuffleReplicas == null) { - loadBalancingPolicy = new TokenAwarePolicy(new RoundRobinPolicy()); - shuffleReplicas = true; - } else { - loadBalancingPolicy = new TokenAwarePolicy(new RoundRobinPolicy(), shuffleReplicas); - } + LoadBalancingPolicy loadBalancingPolicy = new TokenAwarePolicy(new SortingLoadBalancingPolicy(), ordering); Cluster cluster = Cluster.builder() .addContactPoints(sCluster.address(1).getAddress()) @@ -83,11 +144,9 @@ public void should_shuffle_replicas_based_on_configuration(Boolean shuffleReplic try { sCluster.init(); - Session session = cluster.connect(); - // given: A routing key that falls in the token range of node 6. - // Encodes into murmur hash '4874351301193663061' which should belong be owned by node 6 with replicas 7 and 8. + // Encodes into murmur hash '4874351301193663061' which should be owned by node 6 with replicas 7 and 8. ByteBuffer routingKey = TypeCodec.varchar().serialize("This is some sample text", ProtocolVersion.NEWEST_SUPPORTED); // then: The replicas resolved from the cluster metadata must match node 6 and its replicas. @@ -103,26 +162,17 @@ public void should_shuffle_replicas_based_on_configuration(Boolean shuffleReplic statement.setRoutingKey(routingKey); statement.setKeyspace("keyspace"); - boolean shuffledAtLeastOnce = false; - for (int i = 0; i < 1024; i++) { - List queryPlan = Lists.newArrayList(loadBalancingPolicy.newQueryPlan(null, statement)); - assertThat(queryPlan).containsOnlyElementsOf(cluster.getMetadata().getAllHosts()); - - List firstThree = queryPlan.subList(0, 3); - // then: if shuffle replicas was used or using default, the first three hosts returned should be 6,7,8 in any order. - // if shuffle replicas was not used, the first three hosts returned should be 6,7,8 in that order. - if (shuffleReplicas) { - assertThat(firstThree).containsOnlyElementsOf(replicas); - if (!firstThree.equals(replicas)) { - shuffledAtLeastOnce = true; - } - } else { - assertThat(firstThree).containsExactlyElementsOf(replicas); - } - } + List queryPlan = Lists.newArrayList(loadBalancingPolicy.newQueryPlan(null, statement)); + assertThat(queryPlan).containsOnlyElementsOf(cluster.getMetadata().getAllHosts()); - // then: given 1024 query plans, the replicas should be shuffled at least once. - assertThat(shuffledAtLeastOnce).isEqualTo(shuffleReplicas); + List firstThree = queryPlan.subList(0, 3); + // then: if ordering is RANDOM, the first three hosts returned should be 6,7,8 in any order. + // if ordering is TOPOLOGICAL or NEUTRAL, the first three hosts returned should be 6,7,8 in that order. + if (ordering == RANDOM) { + assertThat(firstThree).containsOnlyElementsOf(replicas); + } else { + assertThat(firstThree).containsExactlyElementsOf(replicas); + } } finally { cluster.close(); sCluster.stop(); @@ -156,12 +206,13 @@ public void should_choose_proper_host_based_on_routing_key() { Session session = cluster.connect(); - // Encodes into murmur hash '4557949199137838892' which should belong be owned by node 3. + // Encodes into murmur hash '4557949199137838892' which should be owned by node 3. ByteBuffer routingKey = TypeCodec.varchar().serialize("should_choose_proper_host_based_on_routing_key", ProtocolVersion.NEWEST_SUPPORTED); SimpleStatement statement = new SimpleStatement("select * from table where k=5") .setRoutingKey(routingKey) .setKeyspace("keyspace"); + QueryTracker queryTracker = new QueryTracker(); queryTracker.query(session, 10, statement); // then: The host having that token should be queried. @@ -210,6 +261,7 @@ public void should_choose_host_in_local_dc_when_using_network_topology_strategy_ .setRoutingKey(routingKey) .setKeyspace("keyspace"); + QueryTracker queryTracker = new QueryTracker(); queryTracker.query(session, 10, statement); // then: The local replica (2:1) should be queried and never the remote one. @@ -240,7 +292,7 @@ public void should_use_other_nodes_when_replicas_having_token_are_down() { .withPort(sCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) // Don't shuffle replicas just to keep test deterministic. - .withLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy(), false)) + .withLoadBalancingPolicy(new TokenAwarePolicy(new SortingLoadBalancingPolicy(), NEUTRAL)) .build(); try { @@ -255,58 +307,60 @@ public void should_use_other_nodes_when_replicas_having_token_are_down() { .setRoutingKey(routingKey) .setKeyspace("keyspace"); + QueryTracker queryTracker = new QueryTracker(); queryTracker.query(session, 10, statement); - // then: The node that is the primary for that key's hash is chosen. - queryTracker.assertQueried(sCluster, 1, 1, 0); + // then: primary replica is 4, secondary is 1; since the child policy returns [1,2,3,4], the + // TAP reorders the plan to [1,4,2,3]. Only 1 should be queried + queryTracker.assertQueried(sCluster, 1, 1, 10); queryTracker.assertQueried(sCluster, 1, 2, 0); queryTracker.assertQueried(sCluster, 1, 3, 0); - queryTracker.assertQueried(sCluster, 1, 4, 10); + queryTracker.assertQueried(sCluster, 1, 4, 0); - // when: The primary node owning that key goes down and a query is made. + // when: The secondary node owning that key (1) goes down and a query is made. queryTracker.reset(); - sCluster.stop(cluster, 4); + sCluster.stop(cluster, 1); queryTracker.query(session, 10, statement); - // then: The next replica having that data should be chosen (node 1). - queryTracker.assertQueried(sCluster, 1, 1, 10); + // then: The next replica having that data should be chosen (node 4 - primary replica). + queryTracker.assertQueried(sCluster, 1, 1, 0); queryTracker.assertQueried(sCluster, 1, 2, 0); queryTracker.assertQueried(sCluster, 1, 3, 0); - queryTracker.assertQueried(sCluster, 1, 4, 0); + queryTracker.assertQueried(sCluster, 1, 4, 10); // when: All nodes having that token are down and a query is made. queryTracker.reset(); - sCluster.stop(cluster, 1); + sCluster.stop(cluster, 4); queryTracker.query(session, 10, statement); // then: The remaining nodes which are non-replicas of that token should be used - // delegating to the child policy (RoundRobin). + // delegating to the child policy. queryTracker.assertQueried(sCluster, 1, 1, 0); - queryTracker.assertQueried(sCluster, 1, 2, 5); - queryTracker.assertQueried(sCluster, 1, 3, 5); + queryTracker.assertQueried(sCluster, 1, 2, 10); + queryTracker.assertQueried(sCluster, 1, 3, 0); queryTracker.assertQueried(sCluster, 1, 4, 0); - // when: A replica having that key becomes up and a query is made. + // when: A replica having that key (4) becomes up and a query is made. queryTracker.reset(); - sCluster.start(cluster, 1); + sCluster.start(cluster, 4); queryTracker.query(session, 10, statement); // then: The newly up replica should be queried. - queryTracker.assertQueried(sCluster, 1, 1, 10); + queryTracker.assertQueried(sCluster, 1, 1, 0); queryTracker.assertQueried(sCluster, 1, 2, 0); queryTracker.assertQueried(sCluster, 1, 3, 0); - queryTracker.assertQueried(sCluster, 1, 4, 0); + queryTracker.assertQueried(sCluster, 1, 4, 10); - // when: The primary replicas becomes up and a query is made. + // when: The other replica becomes up and a query is made. queryTracker.reset(); - sCluster.start(cluster, 4); + sCluster.start(cluster, 1); queryTracker.query(session, 10, statement); - // then: The primary replica which is now up should be queried. - queryTracker.assertQueried(sCluster, 1, 1, 0); + // then: The secondary replica (1) which is now up should be queried. + queryTracker.assertQueried(sCluster, 1, 1, 10); queryTracker.assertQueried(sCluster, 1, 2, 0); queryTracker.assertQueried(sCluster, 1, 3, 0); - queryTracker.assertQueried(sCluster, 1, 4, 10); + queryTracker.assertQueried(sCluster, 1, 4, 0); } finally { cluster.close(); sCluster.stop(); @@ -333,7 +387,7 @@ public void should_use_provided_routing_key_boundstatement() { .withPort(sCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) // Don't shuffle replicas just to keep test deterministic. - .withLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy(), false)) + .withLoadBalancingPolicy(new TokenAwarePolicy(new SortingLoadBalancingPolicy(), NEUTRAL)) .build(); try { @@ -351,6 +405,7 @@ public void should_use_provided_routing_key_boundstatement() { ByteBuffer routingKey = TypeCodec.bigint().serialize(33L, ProtocolVersion.NEWEST_SUPPORTED); bs.setRoutingKey(routingKey); + QueryTracker queryTracker = new QueryTracker(); queryTracker.query(session, 10, bs); // Expect only node 3 to have been queried, give it has ownership of that partition @@ -391,43 +446,57 @@ public void should_use_provided_routing_key_boundstatement() { * @test_category load_balancing:token_aware * @jira_ticket JAVA-123 (to ensure routing key buffers are not destroyed). */ - @CCMConfig(createCcm = true, numberOfNodes = 3, createCluster = false) @Test(groups = "long") public void should_properly_generate_and_use_routing_key_for_composite_partition_key() { // given: a 3 node cluster with a keyspace with RF 1. - Cluster cluster = register(Cluster.builder() + CCMBridge ccm = CCMBridge.builder() + .withNodes(3) + .build(); + + ccm.start(); + + Cluster cluster = Cluster.builder() + .addContactPoints(ccm.addressOfNode(1).getAddress()) + .withPort(ccm.getBinaryPort()) + .withNettyOptions(nonQuietClusterCloseOptions) .withLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy())) - .addContactPoints(getContactPoints().get(0)) - .withPort(ccm().getBinaryPort()) - .build()); - Session session = cluster.connect(); - - String table = "composite"; - String ks = TestUtils.generateIdentifier("ks_"); - session.execute(String.format(CREATE_KEYSPACE_SIMPLE_FORMAT, ks, 1)); - session.execute("USE " + ks); - session.execute(String.format("CREATE TABLE %s (k1 int, k2 int, i int, PRIMARY KEY ((k1, k2)))", table)); - - // (1,2) resolves to token '4881097376275569167' which belongs to node 1 so all queries should go to that node. - PreparedStatement insertPs = session.prepare("INSERT INTO " + table + "(k1, k2, i) VALUES (?, ?, ?)"); - BoundStatement insertBs = insertPs.bind(1, 2, 3); - - PreparedStatement selectPs = session.prepare("SELECT * FROM " + table + " WHERE k1=? and k2=?"); - BoundStatement selectBs = selectPs.bind(1, 2); - - // when: executing a prepared statement with a composite partition key. - // then: should query the correct node (1) in for both insert and select queries. - for (int i = 0; i < 10; i++) { - ResultSet rs = session.execute(insertBs); - assertThat(rs.getExecutionInfo().getQueriedHost()).isEqualTo(TestUtils.findHost(cluster, 1)); - - rs = session.execute(selectBs); - assertThat(rs.getExecutionInfo().getQueriedHost()).isEqualTo(TestUtils.findHost(cluster, 1)); - assertThat(rs.isExhausted()).isFalse(); - Row r = rs.one(); - assertThat(rs.isExhausted()).isTrue(); - - assertThat(r.getInt("i")).isEqualTo(3); + .build(); + + try { + + Session session = cluster.connect(); + + String ks = TestUtils.generateIdentifier("ks_"); + session.execute(String.format(CREATE_KEYSPACE_SIMPLE_FORMAT, ks, 1)); + session.execute("USE " + ks); + session.execute("CREATE TABLE composite (k1 int, k2 int, i int, PRIMARY KEY ((k1, k2)))"); + + // (1,2) resolves to token '4881097376275569167' which belongs to node 1 so all queries should go to that node. + PreparedStatement insertPs = session.prepare("INSERT INTO composite(k1, k2, i) VALUES (?, ?, ?)"); + BoundStatement insertBs = insertPs.bind(1, 2, 3); + + PreparedStatement selectPs = session.prepare("SELECT * FROM composite WHERE k1=? and k2=?"); + BoundStatement selectBs = selectPs.bind(1, 2); + + // when: executing a prepared statement with a composite partition key. + // then: should query the correct node (1) in for both insert and select queries. + Host host1 = TestUtils.findHost(cluster, 1); + for (int i = 0; i < 10; i++) { + ResultSet rs = session.execute(insertBs); + assertThat(rs.getExecutionInfo().getQueriedHost()).isEqualTo(host1); + + rs = session.execute(selectBs); + assertThat(rs.getExecutionInfo().getQueriedHost()).isEqualTo(host1); + assertThat(rs.isExhausted()).isFalse(); + Row r = rs.one(); + assertThat(rs.isExhausted()).isTrue(); + + assertThat(r.getInt("i")).isEqualTo(3); + } + } finally { + cluster.close(); + ccm.remove(); } } + } diff --git a/upgrade_guide/README.md b/upgrade_guide/README.md index b278a1491d5..83c2d02a5ef 100644 --- a/upgrade_guide/README.md +++ b/upgrade_guide/README.md @@ -3,6 +3,20 @@ The purpose of this guide is to detail changes made by successive versions of the Java driver. +### 3.5.0 + +The `TokenAwarePolicy` now has a new constructor that takes a `ReplicaOrdering` +argument. One of the advantages of this feature is the new `NEUTRAL` ordering +strategy, which honors its child policy's ordering, i.e., replicas +are returned in the same relative order as in the child policy's query plan. +As an example, if the child policy returns the plan [A, B, C, D], and the replicas +for the query being routed are [D, A, B], then the token aware policy would return +the plan [A, B, D, C]. + +As a consequence, the constructor taking a boolean parameter `shuffleReplicas` +is now deprecated and will be removed in the next major release. + + ### 3.4.0 `QueryBuilder` methods `in`, `lt`, `lte`, `eq`, `gt`, and `gte` now accept From 640f3a12e6a3c50fc529f269e9039c733268dffa Mon Sep 17 00:00:00 2001 From: Alex Ott Date: Wed, 28 Feb 2018 15:03:31 +0100 Subject: [PATCH 068/382] Fix eclipse problems (#954) * fix missing groupId that prevent from correct import into Eclipse * ignore plugins for that there is no m2e connectors --- pom.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pom.xml b/pom.xml index 3f4c5c92a98..07a031e7d10 100644 --- a/pom.xml +++ b/pom.xml @@ -843,6 +843,7 @@ limitations under the License. + org.apache.maven.plugins maven-jar-plugin [2.2,) @@ -853,6 +854,32 @@ limitations under the License. + + + org.codehaus.mojo + clirr-maven-plugin + [2.7,) + + check + + + + + + + + + org.codehaus.gmaven + gmaven-plugin + [1.5,) + + testCompile + + + + + + From 56e800938e5ed3d9ca556899f2353b734d10661e Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Wed, 28 Feb 2018 08:06:21 -0600 Subject: [PATCH 069/382] JAVA-1751: Include defaultTimestamp length in encodedSize for >= V3 (#950) * JAVA-1751: Include defaultTimestamp length in encodedSize for >= V3 QueryProtocolOptions.encodedSize previously incorrectly only accounted for defaultTimestamp length if protocol version was equal to V3. It should be included for all protocol versions >= V3. * JAVA-1770: Fix message size when using Custom Payload --- changelog/README.md | 4 +++- .../main/java/com/datastax/driver/core/CBUtil.java | 11 +++-------- .../java/com/datastax/driver/core/Message.java | 6 ++++++ .../java/com/datastax/driver/core/Requests.java | 14 +++++++------- .../datastax/driver/core/CustomPayloadTest.java | 4 ++-- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 76e180e70f7..4e9604cdf08 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,8 +1,10 @@ ## Changelog -### 3.5.0 (in progress) +### 3.5.0 (In progress) - [improvement] JAVA-1448: TokenAwarePolicy should respect child policy ordering. +- [bug] JAVA-1751: Include defaultTimestamp length in encodedSize for protocol version >= 3. +- [bug] JAVA-1770: Fix message size when using Custom Payload. ### 3.4.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/CBUtil.java b/driver-core/src/main/java/com/datastax/driver/core/CBUtil.java index c252f8d23c2..7996baa892c 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/CBUtil.java +++ b/driver-core/src/main/java/com/datastax/driver/core/CBUtil.java @@ -113,22 +113,17 @@ public static byte[] readBytes(ByteBuf cb) { } } - public static void writeBytes(byte[] bytes, ByteBuf cb) { + public static void writeShortBytes(byte[] bytes, ByteBuf cb) { cb.writeShort(bytes.length); cb.writeBytes(bytes); } - public static void writeBytes(ByteBuffer bytes, ByteBuf cb) { - cb.writeShort(bytes.remaining()); - cb.writeBytes(bytes.duplicate()); - } - - public static int sizeOfBytes(byte[] bytes) { + public static int sizeOfShortBytes(byte[] bytes) { return 2 + bytes.length; } public static int sizeOfBytes(ByteBuffer bytes) { - return 2 + bytes.remaining(); + return 4 + bytes.remaining(); } public static Map readBytesMap(ByteBuf cb) { diff --git a/driver-core/src/main/java/com/datastax/driver/core/Message.java b/driver-core/src/main/java/com/datastax/driver/core/Message.java index b70772aaec3..a78a9d61d83 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Message.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Message.java @@ -342,6 +342,12 @@ protected void encode(ChannelHandlerContext ctx, Request request, List o } coder.encode(request, body, protocolVersion); + if (body.capacity() != messageSize) { + logger.warn("Detected buffer resizing while encoding {} message ({} => {}), " + + "this is a driver bug " + + "(ultimately it does not affect the query, but leads to a small inefficiency)", + request.type, messageSize, body.capacity()); + } out.add(Frame.create(protocolVersion, request.type.opcode, request.getStreamId(), flags, body)); } } diff --git a/driver-core/src/main/java/com/datastax/driver/core/Requests.java b/driver-core/src/main/java/com/datastax/driver/core/Requests.java index 7eeb1e46aba..c42f02b8c16 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Requests.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Requests.java @@ -187,17 +187,17 @@ static class Execute extends Message.Request { static final Message.Coder coder = new Message.Coder() { @Override public void encode(Execute msg, ByteBuf dest, ProtocolVersion version) { - CBUtil.writeBytes(msg.statementId.bytes, dest); + CBUtil.writeShortBytes(msg.statementId.bytes, dest); if (ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(version)) - CBUtil.writeBytes(msg.resultMetadataId.bytes, dest); + CBUtil.writeShortBytes(msg.resultMetadataId.bytes, dest); msg.options.encode(dest, version); } @Override public int encodedSize(Execute msg, ProtocolVersion version) { - int size = CBUtil.sizeOfBytes(msg.statementId.bytes); + int size = CBUtil.sizeOfShortBytes(msg.statementId.bytes); if (ProtocolFeature.PREPARED_METADATA_CHANGES.isSupportedBy(version)) - size += CBUtil.sizeOfBytes(msg.resultMetadataId.bytes); + size += CBUtil.sizeOfShortBytes(msg.resultMetadataId.bytes); size += msg.options.encodedSize(version); return size; } @@ -402,7 +402,7 @@ int encodedSize(ProtocolVersion version) { size += CBUtil.sizeOfValue(pagingState); if (flags.contains(QueryFlag.SERIAL_CONSISTENCY)) size += CBUtil.sizeOfConsistencyLevel(serialConsistency); - if (version == ProtocolVersion.V3 && flags.contains(QueryFlag.DEFAULT_TIMESTAMP)) + if (version.compareTo(ProtocolVersion.V3) >= 0 && flags.contains(QueryFlag.DEFAULT_TIMESTAMP)) size += 8; return size; default: @@ -434,7 +434,7 @@ public void encode(Batch msg, ByteBuf dest, ProtocolVersion version) { if (q instanceof String) CBUtil.writeLongString((String) q, dest); else - CBUtil.writeBytes(((MD5Digest) q).bytes, dest); + CBUtil.writeShortBytes(((MD5Digest) q).bytes, dest); CBUtil.writeValueList(msg.values.get(i), dest); } @@ -449,7 +449,7 @@ public int encodedSize(Batch msg, ProtocolVersion version) { Object q = msg.queryOrIdList.get(i); size += 1 + (q instanceof String ? CBUtil.sizeOfLongString((String) q) - : CBUtil.sizeOfBytes(((MD5Digest) q).bytes)); + : CBUtil.sizeOfShortBytes(((MD5Digest) q).bytes)); size += CBUtil.sizeOfValueList(msg.values.get(i)); } diff --git a/driver-core/src/test/java/com/datastax/driver/core/CustomPayloadTest.java b/driver-core/src/test/java/com/datastax/driver/core/CustomPayloadTest.java index 926578a6d5c..b840aa695c7 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CustomPayloadTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CustomPayloadTest.java @@ -258,8 +258,8 @@ public void should_print_log_message_when_level_trace() throws Exception { session().execute(statement); String logs = appender.waitAndGet(10000); assertThat(logs) - .contains("Sending payload: {k1:0x010203, k2:0x040506} (20 bytes total)") - .contains("Received payload: {k1:0x010203, k2:0x040506} (20 bytes total)"); + .contains("Sending payload: {k1:0x010203, k2:0x040506} (24 bytes total)") + .contains("Received payload: {k1:0x010203, k2:0x040506} (24 bytes total)"); } finally { logger.setLevel(null); logger.removeAppender(appender); From 2e20c9da61a6953c4dcc0dc9fcd4219f399874c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Chantepie?= Date: Wed, 28 Feb 2018 15:06:41 +0100 Subject: [PATCH 070/382] Add equals/hashCode to QueryOptions (#843) --- .../datastax/driver/core/QueryOptions.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/driver-core/src/main/java/com/datastax/driver/core/QueryOptions.java b/driver-core/src/main/java/com/datastax/driver/core/QueryOptions.java index 8c4a9b4f56b..b22e109a7b3 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/QueryOptions.java +++ b/driver-core/src/main/java/com/datastax/driver/core/QueryOptions.java @@ -17,6 +17,7 @@ import com.datastax.driver.core.exceptions.UnsupportedFeatureException; import com.datastax.driver.core.utils.MoreFutures; +import com.datastax.driver.core.utils.MoreObjects; import com.google.common.util.concurrent.Futures; /** @@ -484,4 +485,38 @@ public int getMaxPendingRefreshNodeRequests() { return maxPendingRefreshNodeRequests; } + public boolean equals(Object that) { + if (that == null || !(that instanceof QueryOptions)) { + return false; + } + + QueryOptions other = (QueryOptions) that; + + return (this.consistency.equals(other.consistency) && + this.serialConsistency.equals(other.serialConsistency) && + this.fetchSize == other.fetchSize && + this.defaultIdempotence == other.defaultIdempotence && + this.metadataEnabled == other.metadataEnabled && + this.maxPendingRefreshNodeListRequests == other.maxPendingRefreshNodeListRequests && + this.maxPendingRefreshNodeRequests == other.maxPendingRefreshNodeRequests && + this.maxPendingRefreshSchemaRequests == other.maxPendingRefreshSchemaRequests && + this.refreshNodeListIntervalMillis == other.refreshNodeListIntervalMillis && + this.refreshNodeIntervalMillis == other.refreshNodeIntervalMillis && + this.refreshSchemaIntervalMillis == other.refreshSchemaIntervalMillis && + this.reprepareOnUp == other.reprepareOnUp && + this.prepareOnAllHosts == prepareOnAllHosts + ); + } + + public int hashCode() { + return MoreObjects. + hashCode(consistency, serialConsistency, fetchSize, + defaultIdempotence, metadataEnabled, + maxPendingRefreshNodeListRequests, + maxPendingRefreshNodeRequests, + maxPendingRefreshSchemaRequests, + refreshNodeListIntervalMillis, refreshNodeIntervalMillis, + refreshSchemaIntervalMillis, reprepareOnUp, + prepareOnAllHosts); + } } From e27acfcf8db59eeaf0d13623c877349d2e03630d Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Wed, 28 Feb 2018 08:07:22 -0600 Subject: [PATCH 071/382] JAVA-1760: Add metrics documentation (#958) --- changelog/README.md | 1 + manual/metrics/README.md | 157 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 150 insertions(+), 8 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 4e9604cdf08..0a6ea0dccbf 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -5,6 +5,7 @@ - [improvement] JAVA-1448: TokenAwarePolicy should respect child policy ordering. - [bug] JAVA-1751: Include defaultTimestamp length in encodedSize for protocol version >= 3. - [bug] JAVA-1770: Fix message size when using Custom Payload. +- [documentation] JAVA-1760: Add metrics documentation. ### 3.4.0 diff --git a/manual/metrics/README.md b/manual/metrics/README.md index 78cad50c1e4..78c42af86cf 100644 --- a/manual/metrics/README.md +++ b/manual/metrics/README.md @@ -1,12 +1,153 @@ ## Metrics -*Coming soon... In the meantime, see the javadoc for [Metrics].* +The driver exposes measurements of its internal behavior through the popular [Dropwizard Metrics] +library. Developers can access these metrics and choose to export them to a monitoring tool. - +The driver depends on Metrics 3.2.x, but is compatible with newer versions of Dropwizard Metrics. +For using Metrics 4.x with the driver, see [Metrics 4 Compatibility](#metrics-4-compatibility). -[Metrics]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Metrics.html \ No newline at end of file +### Structure + +Metric names are path-like, dot-separated strings. Metrics are measured at the `Cluster`-level, +thus the driver prefixes them with the name of the `Cluster` they are associated with (see [withClusterName] +for how to configure this), suffixed by `-metrics`. For example: + +``` +cluster1-metrics.connected-to +cluster1-metrics.connection-errors +... +``` + +### Configuration + +By default, metrics are enabled and exposed via JMX as [MXBeans]. + +Some users may find that they don't want the driver to record and expose metrics. To disable +metrics collection, use the [withoutMetrics] builder method, i.e.: + +```java +Cluster cluster = Cluster.builder() + .withoutMetrics() + .build(); +``` + +Note that if you decide to disable metrics, you may also consider excluding metrics as a dependency. +To do this in a maven project: + +```xml + + com.datastax.cassandra + cassandra-driver-core + 3.4.0 + + + io.dropwizard.metrics + metrics-core + + + +``` + +Alternatively, one may not want to expose metrics using JMX. Disabling JMX reporting is simple +as using the [withoutJMXReporting] builder method, i.e.: + +```java +Cluster cluster = Cluster.builder() + .withoutJMXReporting() + .build(); +``` + +### Accessing Cluster Metrics + +`Cluster` metrics may be accessed via the [getMetrics] method. The [Metrics] class offers +direct access to all metrics recorded for the `Cluster` via getter methods. Refer to +the [Metrics javadoc][Metrics] for more details about the metrics offered. + +It is very common for applications to record their own metrics. You can add all metrics +recorded for a `Cluster` to your applications' [MetricRegistry] in the following manner: + +```java +MetricRegistry myRegistery = new MetricRegistry(); +myRegistry.registerAll(cluster.getMetrics().getRegistry()); +``` + +### Registering a Custom Reporter + +Dropwizard Metrics offers a variety of [Reporters] for exporting metrics. To enable reporting, +access the `Cluster`'s metrics via the [getMetrics] method. For example, to enable CSV reporting +every 30 seconds: + +```java +import com.codahale.metrics.*; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +Metrics metrics = cluster.getMetrics(); + +CsvReporter csvReporter = CsvReporter.forRegistry(metrics.getRegistry()) + .convertDurationsTo(TimeUnit.MILLISECONDS) + .convertRatesTo(TimeUnit.SECONDS) + .build(new File(".")); + +csvReporter.start(30, TimeUnit.SECONDS); +``` + +### Metrics 4 Compatibility + +While the driver depends on Metrics 3.2.x, it also works with Metrics 4, with some caveats. + +In Metrics 4, JMX reporting was moved to a separate module, `metrics-jmx`. Because of this you are +likely to encounter the following exception at runtime when initializing a `Cluster`: + +``` +Exception in thread "main" java.lang.NoClassDefFoundError: com/codahale/metrics/JmxReporter + at com.datastax.driver.core.Metrics.(Metrics.java:103) + at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1402) + at com.datastax.driver.core.Cluster.init(Cluster.java:159) + at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:330) + at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:305) + at com.datastax.durationtest.core.DurationTest.createSessions(DurationTest.java:360) + .... +Caused by: java.lang.ClassNotFoundException: com.codahale.metrics.JmxReporter + at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) + at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) + at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) + ... 8 more +``` + +To fix this, use [withoutJMXReporting] when constructing your `Cluster`. If you still desire JMX +reporting, add `metrics-jmx` as a dependency: + +```xml + + io.dropwizard.metrics + metrics-jmx + 4.0.2 + +``` + +Then create your `Cluster` and `JmxReporter` in the following manner: + +```java +Cluster cluster = Cluster.builder() + .withoutJMXReporting() + .build(); + +JmxReporter reporter = + JmxReporter.forRegistry(cluster.getMetrics().getRegistry()) + .inDomain(cluster.getClusterName() + "-metrics") + .build(); + +reporter.start(); +``` + +[Dropwizard Metrics]: http://metrics.dropwizard.io/3.2.2/manual/index.html +[Reporters]: http://metrics.dropwizard.io/3.2.2/manual/core.html#reporters +[MetricRegistry]: http://metrics.dropwizard.io/3.2.2/apidocs/com/codahale/metrics/MetricRegistry.html +[MXBeans]: https://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html +[withClusterName]: https://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Cluster.Builder.html#withClusterName-java.lang.String- +[withoutMetrics]: https://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Cluster.Builder.html#withoutMetrics-- +[withoutJMXReporting]: https://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Cluster.Builder.html#withoutJMXReporting-- +[getMetrics]: https://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Cluster.html#getMetrics-- +[Metrics]: http://docs.datastax.com/en/drivers/java/3.4/com/datastax/driver/core/Metrics.html From 5b5f7b1b035cd22b5536f8efe41ad67bf8543cfb Mon Sep 17 00:00:00 2001 From: Andrew Tolbert Date: Wed, 28 Feb 2018 08:10:12 -0600 Subject: [PATCH 072/382] JAVA-1765: Update dependencies to latest patch versions (#959) --- changelog/README.md | 1 + driver-core/pom.xml | 4 +-- .../datastax/driver/osgi/BundleOptions.java | 2 +- manual/compression/README.md | 6 ++-- manual/speculative_execution/README.md | 2 +- manual/ssl/README.md | 2 +- pom.xml | 29 ++++++++++--------- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/changelog/README.md b/changelog/README.md index 0a6ea0dccbf..5568d69f151 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -6,6 +6,7 @@ - [bug] JAVA-1751: Include defaultTimestamp length in encodedSize for protocol version >= 3. - [bug] JAVA-1770: Fix message size when using Custom Payload. - [documentation] JAVA-1760: Add metrics documentation. +- [improvement] JAVA-1765: Update dependencies to latest patch versions. ### 3.4.0 diff --git a/driver-core/pom.xml b/driver-core/pom.xml index b38c8338152..d17c42bbd53 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -74,8 +74,8 @@ - net.jpountz.lz4 - lz4 + org.lz4 + lz4-java true diff --git a/driver-tests/osgi/src/test/java/com/datastax/driver/osgi/BundleOptions.java b/driver-tests/osgi/src/test/java/com/datastax/driver/osgi/BundleOptions.java index e47b2caebcb..c3a93c9a9ed 100644 --- a/driver-tests/osgi/src/test/java/com/datastax/driver/osgi/BundleOptions.java +++ b/driver-tests/osgi/src/test/java/com/datastax/driver/osgi/BundleOptions.java @@ -76,7 +76,7 @@ public static CompositeOption lz4Bundle() { public Option[] getOptions() { return options( systemProperty("cassandra.compression").value(ProtocolOptions.Compression.LZ4.name()), - mavenBundle("net.jpountz.lz4", "lz4", getVersion("lz4.version")) + mavenBundle("org.lz4", "lz4-java", getVersion("lz4.version")) ); } }; diff --git a/manual/compression/README.md b/manual/compression/README.md index 1c2b73d080b..c6cd8c885df 100644 --- a/manual/compression/README.md +++ b/manual/compression/README.md @@ -25,9 +25,9 @@ Maven dependency: ```xml - net.jpountz.lz4 - lz4 - 1.3.0 + org.lz4 + lz4-java + 1.4.1 ``` diff --git a/manual/speculative_execution/README.md b/manual/speculative_execution/README.md index 38af43c2d7f..1160f8be2a2 100644 --- a/manual/speculative_execution/README.md +++ b/manual/speculative_execution/README.md @@ -117,7 +117,7 @@ explicitly depend on it: org.hdrhistogram HdrHistogram - 2.1.9 + 2.1.10 ``` diff --git a/manual/ssl/README.md b/manual/ssl/README.md index 1e8244d037e..72f70fceb90 100644 --- a/manual/ssl/README.md +++ b/manual/ssl/README.md @@ -153,7 +153,7 @@ add it to your dependencies. There are known runtime incompatibilities between newer versions of netty-tcnative and the version of netty that the driver uses. For best -results, use version 2.0.1.Final. +results, use version 2.0.7.Final. Using netty-tcnative requires JDK 1.7 or above and requires the presence of OpenSSL on the system. It will not fall back to the JDK implementation. diff --git a/pom.xml b/pom.xml index 07a031e7d10..aa08d7c463f 100644 --- a/pom.xml +++ b/pom.xml @@ -45,25 +45,26 @@ UTF-8 UTF-8 - 3.11.1 + 3.11.2 1.6 1.2.17 1.7.25 1.7.25 19.0 - 4.0.47.Final + 4.0.56.Final + 2.0.7.Final 3.2.2 1.1.2.6 - 1.3.0 - 2.1.9 - 2.8.8 + 1.4.1 + 2.1.10 + 2.8.11 - 2.7.9.2 - 2.9.1 + 2.7.9.3 + 2.9.9 1.0 1.0.4 - 2.0.7 - 3.0.27 + 2.0.9 + 3.0.44 2.4.7 2.0.1 2.23.1 @@ -165,8 +166,8 @@ - net.jpountz.lz4 - lz4 + org.lz4 + lz4-java ${lz4.version} @@ -341,7 +342,7 @@ io.netty netty-tcnative - 2.0.1.Final + ${netty-tcnative.version} ${os.detected.classifier} @@ -515,8 +516,8 @@ ${snappy.version} - net.jpountz.lz4 - lz4 + org.lz4 + lz4-java ${lz4.version} From f5d44d3fea093a5c28d59ba0f587e9044e161813 Mon Sep 17 00:00:00 2001 From: Alexandre Dutra Date: Wed, 28 Feb 2018 15:12:08 +0100 Subject: [PATCH 073/382] JAVA-1752: Deprecate DowngradingConsistencyRetryPolicy (#962) --- changelog/README.md | 1 + .../exceptions/QueryConsistencyException.java | 2 +- .../core/exceptions/ReadTimeoutException.java | 4 +- .../DowngradingConsistencyRetryPolicy.java | 18 +- ...ConsistencyRetryPolicyIntegrationTest.java | 1 + .../examples/retry/DowngradingRetry.java | 473 ++++++++++++++++++ upgrade_guide/README.md | 59 ++- 7 files changed, 539 insertions(+), 19 deletions(-) create mode 100644 driver-examples/src/main/java/com/datastax/driver/examples/retry/DowngradingRetry.java diff --git a/changelog/README.md b/changelog/README.md index 5568d69f151..24d4e4e912c 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -7,6 +7,7 @@ - [bug] JAVA-1770: Fix message size when using Custom Payload. - [documentation] JAVA-1760: Add metrics documentation. - [improvement] JAVA-1765: Update dependencies to latest patch versions. +- [improvement] JAVA-1752: Deprecate DowngradingConsistencyRetryPolicy. ### 3.4.0 diff --git a/driver-core/src/main/java/com/datastax/driver/core/exceptions/QueryConsistencyException.java b/driver-core/src/main/java/com/datastax/driver/core/exceptions/QueryConsistencyException.java index 8e03844d8b7..434358c6ecd 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/exceptions/QueryConsistencyException.java +++ b/driver-core/src/main/java/com/datastax/driver/core/exceptions/QueryConsistencyException.java @@ -65,7 +65,7 @@ public ConsistencyLevel getConsistencyLevel() { } /** - * The number of replica that had acknowledged/responded to the operation + * The number of replicas that had acknowledged/responded to the operation * before it failed. * * @return the number of replica that had acknowledged/responded the diff --git a/driver-core/src/main/java/com/datastax/driver/core/exceptions/ReadTimeoutException.java b/driver-core/src/main/java/com/datastax/driver/core/exceptions/ReadTimeoutException.java index f3de64a9e7a..09885c16b04 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/exceptions/ReadTimeoutException.java +++ b/driver-core/src/main/java/com/datastax/driver/core/exceptions/ReadTimeoutException.java @@ -66,8 +66,8 @@ else if (!dataPresent) *

* During reads, Cassandra doesn't request data from every replica to * minimize internal network traffic. Instead, some replicas are only asked - * for a checksum of the data. A read timeout may occurred even if enough - * replicas have responded to fulfill the consistency level if only checksum + * for a checksum of the data. A read timeout may have occurred even if enough + * replicas have responded to fulfill the consistency level, if only checksum * responses have been received. This method allows to detect that case. * * @return whether the data was amongst the received replica responses. diff --git a/driver-core/src/main/java/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.java b/driver-core/src/main/java/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.java index 597ed878864..f10610917d4 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.java +++ b/driver-core/src/main/java/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.java @@ -63,7 +63,7 @@ * on the information the Cassandra coordinator node returns, retrying the * operation with the initially requested consistency has a chance to * succeed, do it. Otherwise, if based on this information we know the - * initially requested consistency level cannot be achieve currently, then: + * initially requested consistency level cannot be achieved currently, then: *