use of org.apache.cassandra.utils.CassandraVersion in project cassandra by apache.
the class Gossiper method getReleaseVersionsWithPort.
public Map<String, List<String>> getReleaseVersionsWithPort() {
Map<String, List<String>> results = new HashMap<>();
Iterable<InetAddressAndPort> allHosts = Iterables.concat(Gossiper.instance.getLiveMembers(), Gossiper.instance.getUnreachableMembers());
for (InetAddressAndPort host : allHosts) {
CassandraVersion version = getReleaseVersion(host);
String stringVersion = version == null ? "" : version.toString();
List<String> hosts = results.get(stringVersion);
if (hosts == null) {
hosts = new ArrayList<>();
results.put(stringVersion, hosts);
}
hosts.add(host.getHostAddressAndPort());
}
return results;
}
use of org.apache.cassandra.utils.CassandraVersion in project cassandra by apache.
the class SystemKeyspaceTest method getOlderVersionString.
private String getOlderVersionString() {
String version = FBUtilities.getReleaseVersionString();
CassandraVersion semver = new CassandraVersion(version.contains("-") ? version.substring(0, version.indexOf('-')) : version);
return (String.format("%s.%s.%s", semver.major - 1, semver.minor, semver.patch));
}
use of org.apache.cassandra.utils.CassandraVersion in project cassandra by apache.
the class StartupMessage method execute.
@Override
protected Message.Response execute(QueryState state, long queryStartNanoTime, boolean traceRequest) {
String cqlVersion = options.get(CQL_VERSION);
if (cqlVersion == null)
throw new ProtocolException("Missing value CQL_VERSION in STARTUP message");
try {
if (new CassandraVersion(cqlVersion).compareTo(new CassandraVersion("2.99.0")) < 0)
throw new ProtocolException(String.format("CQL version %s is not supported by the binary protocol (supported version are >= 3.0.0)", cqlVersion));
} catch (IllegalArgumentException e) {
throw new ProtocolException(e.getMessage());
}
if (options.containsKey(COMPRESSION)) {
String compression = options.get(COMPRESSION).toLowerCase();
if (compression.equals("snappy")) {
if (Compressor.SnappyCompressor.instance == null)
throw new ProtocolException("This instance does not support Snappy compression");
if (getSource().header.version.isGreaterOrEqualTo(ProtocolVersion.V5))
throw new ProtocolException("Snappy compression is not supported in protocol V5");
connection.setCompressor(Compressor.SnappyCompressor.instance);
} else if (compression.equals("lz4")) {
connection.setCompressor(Compressor.LZ4Compressor.instance);
} else {
throw new ProtocolException(String.format("Unknown compression algorithm: %s", compression));
}
}
connection.setThrowOnOverload("1".equals(options.get(THROW_ON_OVERLOAD)));
ClientState clientState = state.getClientState();
String driverName = options.get(DRIVER_NAME);
if (null != driverName) {
clientState.setDriverName(driverName);
clientState.setDriverVersion(options.get(DRIVER_VERSION));
}
if (DatabaseDescriptor.getAuthenticator().requireAuthentication())
return new AuthenticateMessage(DatabaseDescriptor.getAuthenticator().getClass().getName());
else
return new ReadyMessage();
}
use of org.apache.cassandra.utils.CassandraVersion in project cassandra by apache.
the class MixedModeFuzzTest method mixedModeFuzzTest.
@Test
public void mixedModeFuzzTest() throws Throwable {
try (ICluster<IInvokableInstance> c = builder().withNodes(2).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).withInstanceInitializer(PrepareBehaviour::oldNewBehaviour).start()) {
// Long string to make us invalidate caches occasionally
String veryLongString = "very";
for (int i = 0; i < 2; i++) veryLongString += veryLongString;
final String qualified = "SELECT pk as " + veryLongString + "%d, ck as " + veryLongString + "%d FROM ks%d.tbl";
final String unqualified = "SELECT pk as " + veryLongString + "%d, ck as " + veryLongString + "%d FROM tbl";
int KEYSPACES = 3;
final int STATEMENTS_PER_KS = 2;
for (int i = 0; i < KEYSPACES; i++) {
c.schemaChange(withKeyspace("CREATE KEYSPACE ks" + i + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2};"));
c.schemaChange(withKeyspace("CREATE TABLE ks" + i + ".tbl (pk int, ck int, PRIMARY KEY (pk, ck));"));
for (int j = 0; j < i; j++) c.coordinator(1).execute("INSERT INTO ks" + i + ".tbl (pk, ck) VALUES (?, ?)", ConsistencyLevel.ALL, 1, j);
}
List<Thread> threads = new ArrayList<>();
AtomicBoolean interrupt = new AtomicBoolean(false);
AtomicReference<Throwable> thrown = new AtomicReference<>();
int INFREQUENT_ACTION_COEF = 100;
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(20);
for (int i = 0; i < 3; i++) {
int seed = i;
threads.add(new Thread(() -> {
com.datastax.driver.core.Cluster cluster = null;
Map<String, Session> sessions = new HashMap<>();
try {
AtomicBoolean nodeWithFix = new AtomicBoolean(false);
Supplier<Cluster> clusterSupplier = () -> {
return com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").addContactPoint("127.0.0.2").build();
};
AtomicBoolean allUpgraded = new AtomicBoolean(false);
Random rng = new Random(seed);
boolean reconnected = false;
Map<Pair<Integer, Integer>, PreparedStatement> qualifiedStatements = new HashMap<>();
Map<Pair<Integer, Integer>, PreparedStatement> unqualifiedStatements = new HashMap<>();
cluster = clusterSupplier.get();
for (int j = 0; j < KEYSPACES; j++) {
String ks = "ks" + j;
sessions.put(ks, cluster.connect(ks));
Assert.assertEquals(sessions.get(ks).getLoggedKeyspace(), ks);
}
long firstVersionBump = System.nanoTime() + TimeUnit.SECONDS.toNanos(5);
long reconnectAfter = System.nanoTime() + TimeUnit.SECONDS.toNanos(15);
while (!interrupt.get() && (System.nanoTime() < deadline)) {
nodeWithFix.set(rng.nextBoolean());
final int ks = rng.nextInt(KEYSPACES);
final int statementIdx = rng.nextInt(STATEMENTS_PER_KS);
final Pair<Integer, Integer> statementId = Pair.create(ks, statementIdx);
int v = rng.nextInt(INFREQUENT_ACTION_COEF + 1);
Action[] pool;
if (v == INFREQUENT_ACTION_COEF)
pool = infrequent;
else
pool = frequent;
Action action = pool[rng.nextInt(pool.length)];
// logger.info(String.format("Executing %s on the node %s. ks %d", action, nodeWithFix.get() ? "1" : "2", ks));
switch(action) {
case BUMP_VERSION:
if (System.nanoTime() < firstVersionBump)
break;
c.stream().forEach(node -> node.runOnInstance(() -> {
if (version.get().equals(INITIAL_VERSION)) {
CassandraVersion upgradeTo = QueryProcessor.NEW_PREPARED_STATEMENT_BEHAVIOUR_SINCE_40;
while (!version.get().equals(upgradeTo)) {
if (version.compareAndSet(INITIAL_VERSION, upgradeTo)) {
logger.info("Bumped version to " + upgradeTo);
break;
}
}
}
}));
break;
case EXECUTE_QUALIFIED:
if (!qualifiedStatements.containsKey(statementId))
continue;
try {
int counter = 0;
BoundStatement boundStatement = qualifiedStatements.get(statementId).bind();
boundStatement.setHost(getHost(cluster, nodeWithFix.get()));
for (Iterator<Object[]> iter = RowUtil.toObjects(sessions.get("ks" + ks).execute(boundStatement)); iter.hasNext(); ) {
Object[] current = iter.next();
int v0 = (int) current[0];
int v1 = (int) current[1];
Assert.assertEquals(v0, 1);
Assert.assertEquals(v1, counter++);
}
if (nodeWithFix.get())
Assert.assertEquals(ks, counter);
} catch (Throwable t) {
if (t.getCause() != null && t.getCause().getMessage().contains("Statement was prepared on keyspace"))
continue;
throw t;
}
break;
case EXECUTE_UNQUALIFIED:
if (!unqualifiedStatements.containsKey(statementId))
continue;
try {
BoundStatement boundStatement = unqualifiedStatements.get(statementId).bind();
boundStatement.setHost(getHost(cluster, nodeWithFix.get()));
int counter = 0;
for (Iterator<Object[]> iter = RowUtil.toObjects(sessions.get("ks" + ks).execute(boundStatement)); iter.hasNext(); ) {
Object[] current = iter.next();
int v0 = (int) current[0];
int v1 = (int) current[1];
Assert.assertEquals(v0, 1);
Assert.assertEquals(v1, counter++);
}
if (nodeWithFix.get() && allUpgraded.get()) {
Assert.assertEquals(unqualifiedStatements.get(statementId).getQueryKeyspace() + " " + ks + " " + statementId, ks, counter);
}
} catch (Throwable t) {
if (t.getMessage().contains("ID mismatch while trying to reprepare") || (t.getCause() != null && t.getCause().getMessage().contains("Statement was prepared on keyspace"))) {
logger.info("Detected id mismatch, skipping as it is expected: ");
continue;
}
throw t;
}
break;
case FORGET_PREPARED:
Map<Pair<Integer, Integer>, PreparedStatement> toCleanup = rng.nextBoolean() ? qualifiedStatements : unqualifiedStatements;
Set<Pair<Integer, Integer>> toDrop = new HashSet<>();
for (Pair<Integer, Integer> e : toCleanup.keySet()) {
if (rng.nextBoolean())
toDrop.add(e);
}
for (Pair<Integer, Integer> e : toDrop) toCleanup.remove(e);
toDrop.clear();
break;
case CLEAR_CACHES:
if (!nodeWithFix.get() && !allUpgraded.get())
continue;
c.get(nodeWithFix.get() ? 1 : 2).runOnInstance(() -> {
SystemKeyspace.loadPreparedStatements((id, query, keyspace) -> {
if (rng.nextBoolean())
QueryProcessor.instance.evictPrepared(id);
return true;
});
});
break;
case PREPARE_QUALIFIED:
if (unqualifiedStatements.containsKey(statementId))
continue;
try {
String qs = String.format(qualified, statementIdx, statementIdx, ks);
String keyspace = "ks" + ks;
PreparedStatement preparedQualified = sessions.get("ks" + ks).prepare(qs);
// With prepared qualified, keyspace will be set to the keyspace of the statement when it was first executed
if (allUpgraded.get())
PreparedStatementHelper.assertHashWithoutKeyspace(preparedQualified, qs, keyspace);
qualifiedStatements.put(statementId, preparedQualified);
} catch (Throwable t) {
throw t;
}
break;
case PREPARE_UNQUALIFIED:
if (unqualifiedStatements.containsKey(statementId))
continue;
try {
String qs = String.format(unqualified, statementIdx, statementIdx);
// we don't know where it's going to be executed
PreparedStatement preparedUnqalified = sessions.get("ks" + ks).prepare(qs);
unqualifiedStatements.put(Pair.create(ks, statementIdx), preparedUnqalified);
} catch (InvalidQueryException iqe) {
if (!iqe.getMessage().contains("No keyspace has been"))
throw iqe;
} catch (Throwable t) {
throw t;
}
break;
case BOUNCE_CLIENT:
if (System.nanoTime() < reconnectAfter)
break;
if (!reconnected) {
for (Session s : sessions.values()) s.close();
cluster.close();
cluster = clusterSupplier.get();
for (int j = 0; j < KEYSPACES; j++) sessions.put("ks" + j, cluster.connect("ks" + j));
qualifiedStatements.clear();
unqualifiedStatements.clear();
reconnected = true;
}
break;
}
}
} catch (Throwable t) {
interrupt.set(true);
t.printStackTrace();
while (true) {
Throwable seen = thrown.get();
Throwable merged = Throwables.merge(seen, t);
if (thrown.compareAndSet(seen, merged))
break;
}
throw t;
} finally {
logger.info("Exiting...");
if (cluster != null)
cluster.close();
}
}));
}
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
if (thrown.get() != null)
throw thrown.get();
}
}
use of org.apache.cassandra.utils.CassandraVersion in project cassandra by apache.
the class GossiperTest method testHasVersion3Nodes.
@Test
public void testHasVersion3Nodes() throws Exception {
Gossiper.instance.start(0);
Gossiper.instance.expireUpgradeFromVersion();
VersionedValue.VersionedValueFactory factory = new VersionedValue.VersionedValueFactory(null);
EndpointState es = new EndpointState((HeartBeatState) null);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion(CURRENT_VERSION.toString()));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.1"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.1"));
es = new EndpointState((HeartBeatState) null);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion("3.11.3"));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.2"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.2"));
es = new EndpointState((HeartBeatState) null);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion("3.0.0"));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.3"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.3"));
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.0")) < 0);
assertTrue(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.1")) < 0);
assertTrue(Gossiper.instance.hasMajorVersion3Nodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.3"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.3"));
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.0")) < 0);
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.1")) < 0);
assertTrue(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.12")) < 0);
assertTrue(Gossiper.instance.hasMajorVersion3Nodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.2"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.2"));
assertEquals(SystemKeyspace.CURRENT_VERSION, Gossiper.instance.upgradeFromVersionSupplier.get().value());
}
Aggregations