diff --git a/build.xml b/build.xml
index 50937e15ec..3be96e47b9 100644
--- a/build.xml
+++ b/build.xml
@@ -551,6 +551,7 @@
+
@@ -686,6 +687,7 @@
+
diff --git a/test/distributed/org/apache/cassandra/distributed/Cluster.java b/test/distributed/org/apache/cassandra/distributed/Cluster.java
index d3533d3fa9..ee01874a44 100644
--- a/test/distributed/org/apache/cassandra/distributed/Cluster.java
+++ b/test/distributed/org/apache/cassandra/distributed/Cluster.java
@@ -24,30 +24,44 @@ import java.util.List;
import java.util.function.Consumer;
import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.distributed.api.IInstanceConfig;
import org.apache.cassandra.distributed.impl.AbstractCluster;
-import org.apache.cassandra.distributed.impl.IInvokableInstance;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.impl.InstanceConfig;
-import org.apache.cassandra.distributed.impl.Versions;
+import org.apache.cassandra.distributed.shared.Builder;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
+import org.apache.cassandra.distributed.shared.Versions;
/**
* A simple cluster supporting only the 'current' Cassandra version, offering easy access to the convenience methods
* of IInvokableInstance on each node.
*/
-public class Cluster extends AbstractCluster implements ICluster, AutoCloseable
+public class Cluster extends AbstractCluster
{
- private Cluster(File root, Versions.Version version, List configs, ClassLoader sharedClassLoader)
+
+ private Cluster(File root, Versions.Version version, List configs, ClassLoader sharedClassLoader)
{
super(root, version, configs, sharedClassLoader);
}
- protected IInvokableInstance newInstanceWrapper(int generation, Versions.Version version, InstanceConfig config)
+ protected IInvokableInstance newInstanceWrapper(int generation, Versions.Version version, IInstanceConfig config)
{
return new Wrapper(generation, version, config);
}
public static Builder build()
{
- return new Builder<>(Cluster::new);
+ return new Builder(Cluster::new)
+ {
+ {
+ withVersion(CURRENT_VERSION);
+ }
+
+ protected IInstanceConfig generateConfig(int nodeNum, String ipAddress, NetworkTopology networkTopology, File root, String token, String seedIp)
+ {
+ return InstanceConfig.generate(nodeNum, ipAddress, networkTopology, root, token, seedIp);
+ }
+ };
}
public static Builder build(int nodeCount)
@@ -55,7 +69,7 @@ public class Cluster extends AbstractCluster implements IClu
return build().withNodes(nodeCount);
}
- public static Cluster create(int nodeCount, Consumer configUpdater) throws IOException
+ public static Cluster create(int nodeCount, Consumer configUpdater) throws IOException
{
return build(nodeCount).withConfig(configUpdater).start();
}
diff --git a/test/distributed/org/apache/cassandra/distributed/UpgradeableCluster.java b/test/distributed/org/apache/cassandra/distributed/UpgradeableCluster.java
index 6ffdc6287b..8566897d93 100644
--- a/test/distributed/org/apache/cassandra/distributed/UpgradeableCluster.java
+++ b/test/distributed/org/apache/cassandra/distributed/UpgradeableCluster.java
@@ -22,11 +22,13 @@ import java.io.File;
import java.util.List;
import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.distributed.api.IInstanceConfig;
import org.apache.cassandra.distributed.impl.AbstractCluster;
-import org.apache.cassandra.distributed.impl.IInvokableInstance;
-import org.apache.cassandra.distributed.impl.IUpgradeableInstance;
+import org.apache.cassandra.distributed.api.IUpgradeableInstance;
import org.apache.cassandra.distributed.impl.InstanceConfig;
-import org.apache.cassandra.distributed.impl.Versions;
+import org.apache.cassandra.distributed.shared.Builder;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
+import org.apache.cassandra.distributed.shared.Versions;
/**
* A multi-version cluster, offering only the cross-version API
@@ -35,21 +37,36 @@ import org.apache.cassandra.distributed.impl.Versions;
* to permit upgrade tests to perform cluster operations without updating the cross-version API,
* so long as one node is up-to-date.
*/
-public class UpgradeableCluster extends AbstractCluster implements ICluster, AutoCloseable
+public class UpgradeableCluster extends AbstractCluster implements AutoCloseable
{
- private UpgradeableCluster(File root, Versions.Version version, List configs, ClassLoader sharedClassLoader)
+ private UpgradeableCluster(File root, Versions.Version version, List configs, ClassLoader sharedClassLoader)
{
super(root, version, configs, sharedClassLoader);
}
- protected IUpgradeableInstance newInstanceWrapper(int generation, Versions.Version version, InstanceConfig config)
+ protected IUpgradeableInstance newInstanceWrapper(int generation, Versions.Version version, IInstanceConfig config)
{
return new Wrapper(generation, version, config);
}
public static Builder build()
{
- return new Builder<>(UpgradeableCluster::new);
+ return new Builder(UpgradeableCluster::new)
+ {
+ {
+ withVersion(CURRENT_VERSION);
+ }
+
+ protected void setupLogging(File file)
+ {
+ setupLogging(file);
+ }
+
+ protected IInstanceConfig generateConfig(int nodeNum, String ipAddress, NetworkTopology networkTopology, File root, String token, String seedIp)
+ {
+ return InstanceConfig.generate(nodeNum, ipAddress, networkTopology, root, token, seedIp);
+ }
+ };
}
public static Builder build(int nodeCount)
diff --git a/test/distributed/org/apache/cassandra/distributed/api/Feature.java b/test/distributed/org/apache/cassandra/distributed/api/Feature.java
deleted file mode 100644
index b4ba03630c..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/Feature.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-public enum Feature
-{
- NETWORK, GOSSIP, NATIVE_PROTOCOL
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/ICluster.java b/test/distributed/org/apache/cassandra/distributed/api/ICluster.java
deleted file mode 100644
index 091e5f048a..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/ICluster.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import org.apache.cassandra.locator.InetAddressAndPort;
-
-import java.util.stream.Stream;
-
-public interface ICluster
-{
-
- IInstance get(int i);
- IInstance get(InetAddressAndPort endpoint);
- int size();
- Stream extends IInstance> stream();
- Stream extends IInstance> stream(String dcName);
- Stream extends IInstance> stream(String dcName, String rackName);
- IMessageFilters filters();
-
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/ICoordinator.java b/test/distributed/org/apache/cassandra/distributed/api/ICoordinator.java
deleted file mode 100644
index fe969b181c..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/ICoordinator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import java.util.Iterator;
-import java.util.UUID;
-import java.util.concurrent.Future;
-
-// The cross-version API requires that a Coordinator can be constructed without any constructor arguments
-public interface ICoordinator
-{
- // a bit hacky, but ConsistencyLevel draws in too many dependent classes, so we cannot have a cross-version
- // method signature that accepts ConsistencyLevel directly. So we just accept an Enum> and cast.
- default Object[][] execute(String query, Enum> consistencyLevel, Object... boundValues)
- {
- return executeWithResult(query, consistencyLevel, boundValues).toObjectArrays();
- }
- QueryResult executeWithResult(String query, Enum> consistencyLevel, Object... boundValues);
-
- Iterator executeWithPaging(String query, Enum> consistencyLevel, int pageSize, Object... boundValues);
-
- Future asyncExecuteWithTracing(UUID sessionId, String query, Enum> consistencyLevel, Object... boundValues);
- Object[][] executeWithTracing(UUID sessionId, String query, Enum> consistencyLevel, Object... boundValues);
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IInstance.java b/test/distributed/org/apache/cassandra/distributed/api/IInstance.java
deleted file mode 100644
index 23ccd7c943..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/IInstance.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import org.apache.cassandra.locator.InetAddressAndPort;
-
-import java.util.UUID;
-import java.util.concurrent.Future;
-
-// The cross-version API requires that an Instance has a constructor signature of (IInstanceConfig, ClassLoader)
-public interface IInstance extends IIsolatedExecutor
-{
- ICoordinator coordinator();
- IListen listen();
-
- void schemaChangeInternal(String query);
- public Object[][] executeInternal(String query, Object... args);
-
- IInstanceConfig config();
- public InetAddressAndPort broadcastAddressAndPort();
- UUID schemaVersion();
-
- void startup();
- boolean isShutdown();
- Future shutdown();
- Future shutdown(boolean graceful);
-
- int liveMemberCount();
-
- NodeToolResult nodetoolResult(boolean withNotifications, String... commandAndArgs);
- default NodeToolResult nodetoolResult(String... commandAndArgs)
- {
- return nodetoolResult(true, commandAndArgs);
- }
- default int nodetool(String... commandAndArgs) {
- return nodetoolResult(commandAndArgs).getRc();
- }
- void uncaughtException(Thread t, Throwable e);
-
- /**
- * Return the number of times the instance tried to call {@link System#exit(int)}.
- *
- * When the instance is shutdown, this state should be saved, but in case not possible should return {@code -1}
- * to indicate "unknown".
- */
- long killAttempts();
-
- // these methods are not for external use, but for simplicity we leave them public and on the normal IInstance interface
- void startup(ICluster cluster);
- void receiveMessage(IMessage message);
-
- int getMessagingVersion();
- void setMessagingVersion(InetAddressAndPort endpoint, int version);
-
- void flush(String keyspace);
- void forceCompact(String keyspace, String table);
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IInstanceConfig.java b/test/distributed/org/apache/cassandra/distributed/api/IInstanceConfig.java
deleted file mode 100644
index e451441897..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/IInstanceConfig.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import org.apache.cassandra.distributed.impl.NetworkTopology;
-import org.apache.cassandra.locator.InetAddressAndPort;
-import org.apache.cassandra.utils.Pair;
-
-import java.util.Map;
-import java.util.UUID;
-
-public interface IInstanceConfig
-{
- int num();
- UUID hostId();
- InetAddressAndPort broadcastAddressAndPort();
- NetworkTopology networkTopology();
-
- default public String localRack()
- {
- return networkTopology().localRack(broadcastAddressAndPort());
- }
-
- default public String localDatacenter()
- {
- return networkTopology().localDC(broadcastAddressAndPort());
- }
-
- /**
- * write the specified parameters to the Config object; we do not specify Config as the type to support a Config
- * from any ClassLoader; the implementation must not directly access any fields of the Object, or cast it, but
- * must use the reflection API to modify the state
- */
- void propagate(Object writeToConfig);
-
- /**
- * Validates whether the config properties are within range of accepted values.
- */
- void validate();
- Object get(String fieldName);
- String getString(String fieldName);
- int getInt(String fieldName);
- boolean has(Feature featureFlag);
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IIsolatedExecutor.java b/test/distributed/org/apache/cassandra/distributed/api/IIsolatedExecutor.java
deleted file mode 100644
index 6bb41d7969..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/IIsolatedExecutor.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import java.io.Serializable;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * Represents a clean way to handoff evaluation of some work to an executor associated
- * with a node's lifetime.
- *
- * There is no transfer of execution to the parallel class hierarchy.
- *
- * Classes, such as Instance, that are themselves instantiated on the correct ClassLoader, utilise this class
- * to ensure the lifetime of any thread evaluating one of its method invocations matches the lifetime of the class itself.
- * Since they are instantiated on the correct ClassLoader, sharing only the interface, there is no serialization necessary.
- */
-public interface IIsolatedExecutor
-{
- public interface CallableNoExcept extends Callable { public O call(); }
- public interface SerializableCallable extends CallableNoExcept, Serializable { }
- public interface SerializableRunnable extends Runnable, Serializable {}
- public interface SerializableConsumer extends Consumer, Serializable {}
- public interface SerializableBiConsumer extends BiConsumer, Serializable {}
- public interface SerializableFunction extends Function, Serializable {}
- public interface SerializableBiFunction extends BiFunction, Serializable {}
- public interface TriFunction
- {
- O apply(I1 i1, I2 i2, I3 i3);
- }
- public interface SerializableTriFunction extends Serializable, TriFunction { }
-
- Future shutdown();
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- CallableNoExcept> async(CallableNoExcept call);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- CallableNoExcept sync(CallableNoExcept call);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- CallableNoExcept> async(Runnable run);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- Runnable sync(Runnable run);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- Function> async(Consumer consumer);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- Consumer sync(Consumer consumer);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- BiFunction> async(BiConsumer consumer);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- BiConsumer sync(BiConsumer consumer);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- Function> async(Function f);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- Function sync(Function f);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- BiFunction> async(BiFunction f);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- BiFunction sync(BiFunction f);
-
- /**
- * Convert the execution to one performed asynchronously on the IsolatedExecutor, returning a Future of the execution result
- */
- TriFunction> async(TriFunction f);
-
- /**
- * Convert the execution to one performed synchronously on the IsolatedExecutor
- */
- TriFunction sync(TriFunction f);
-
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IMessage.java b/test/distributed/org/apache/cassandra/distributed/api/IMessage.java
deleted file mode 100644
index f2594caa7a..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/IMessage.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import java.io.Serializable;
-
-import org.apache.cassandra.locator.InetAddressAndPort;
-
-/**
- * A cross-version interface for delivering internode messages via message sinks.
- *
- * Message implementations should be serializable so we could load into instances.
- */
-public interface IMessage extends Serializable
-{
- int verb();
- byte[] bytes();
- // TODO: need to make this a long
- int id();
- int version();
- InetAddressAndPort from();
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IMessageFilters.java b/test/distributed/org/apache/cassandra/distributed/api/IMessageFilters.java
deleted file mode 100644
index f2cd6ee232..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/api/IMessageFilters.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.api;
-
-import java.util.function.Predicate;
-
-public interface IMessageFilters
-{
- public interface Filter
- {
- Filter off();
- Filter on();
- }
-
- public interface Builder
- {
- Builder from(int ... nums);
- Builder to(int ... nums);
-
- Builder verbs(int... verbs);
- Builder allVerbs();
-
- Builder inbound(boolean inbound);
-
- default Builder inbound()
- {
- return inbound(true);
- }
-
- default Builder outbound()
- {
- return inbound(false);
- }
-
- /**
- * Every message for which matcher returns `true` will be _dropped_ (assuming all
- * other matchers in the chain will return `true` as well).
- */
- Builder messagesMatching(Matcher filter);
- Filter drop();
- }
-
- public interface Matcher
- {
- boolean matches(int from, int to, IMessage message);
-
- static Matcher of(Predicate fn) {
- return (from, to, m) -> fn.test(m);
- }
- }
-
- Builder inbound(boolean inbound);
- default Builder inbound() {
- return inbound(true);
- }
- default Builder outbound() {
- return inbound(false);
- }
- default Builder verbs(int... verbs) {
- return inbound().verbs(verbs);
- }
- default Builder allVerbs() {
- return inbound().allVerbs();
- }
- void reset();
-
- /**
- * Checks if the message should be delivered. This is expected to run on "inbound", or on the reciever of
- * the message (instance.config.num == to).
- *
- * @return {@code true} value returned by the implementation implies that the message was
- * not matched by any filters and therefore should be delivered.
- */
- boolean permitInbound(int from, int to, IMessage msg);
-
- /**
- * Checks if the message should be delivered. This is expected to run on "outbound", or on the sender of
- * the message (instance.config.num == from).
- *
- * @return {@code true} value returned by the implementation implies that the message was
- * not matched by any filters and therefore should be delivered.
- */
- boolean permitOutbound(int from, int to, IMessage msg);
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/AbstractCluster.java b/test/distributed/org/apache/cassandra/distributed/impl/AbstractCluster.java
index 371de54f0c..bcfaaf5157 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/AbstractCluster.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/AbstractCluster.java
@@ -19,10 +19,7 @@
package org.apache.cassandra.distributed.impl;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -35,7 +32,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
-import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
@@ -43,8 +39,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.db.ColumnFamilyStore;
-import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.db.Keyspace;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.apache.cassandra.distributed.api.Feature;
import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.dht.IPartitioner;
@@ -52,13 +48,18 @@ import org.apache.cassandra.dht.Token;
import org.apache.cassandra.distributed.api.ICoordinator;
import org.apache.cassandra.distributed.api.IInstance;
import org.apache.cassandra.distributed.api.IInstanceConfig;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.api.IIsolatedExecutor;
import org.apache.cassandra.distributed.api.IListen;
import org.apache.cassandra.distributed.api.IMessage;
import org.apache.cassandra.distributed.api.IMessageFilters;
+import org.apache.cassandra.distributed.api.IUpgradeableInstance;
import org.apache.cassandra.distributed.api.NodeToolResult;
+import org.apache.cassandra.distributed.shared.InstanceClassLoader;
+import org.apache.cassandra.distributed.shared.MessageFilters;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
+import org.apache.cassandra.distributed.shared.Versions;
import org.apache.cassandra.io.util.FileUtils;
-import org.apache.cassandra.locator.InetAddressAndPort;
import org.apache.cassandra.net.Verb;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.concurrent.SimpleCondition;
@@ -87,8 +88,10 @@ import org.apache.cassandra.utils.concurrent.SimpleCondition;
* handlers for internode to have more control over it. Messaging is wired by passing verbs manually.
* coordinator-handling code and hooks to the callbacks can be found in {@link Coordinator}.
*/
-public abstract class AbstractCluster implements ICluster, AutoCloseable
+public abstract class AbstractCluster implements ICluster, AutoCloseable
{
+ public static Versions.Version CURRENT_VERSION = new Versions.Version(FBUtilities.getReleaseVersionString(), Versions.getClassPath());;
+
// WARNING: we have this logger not (necessarily) for logging, but
// to ensure we have instantiated the main classloader's LoggerFactory (and any LogbackStatusListener)
// before we instantiate any for a new instance
@@ -100,7 +103,7 @@ public abstract class AbstractCluster implements ICluster,
// mutated by starting/stopping a node
private final List instances;
- private final Map instanceMap;
+ private final Map instanceMap;
private final Versions.Version initialVersion;
@@ -111,7 +114,7 @@ public abstract class AbstractCluster implements ICluster,
protected class Wrapper extends DelegatingInvokableInstance implements IUpgradeableInstance
{
private final int generation;
- private final InstanceConfig config;
+ private final IInstanceConfig config;
private volatile IInvokableInstance delegate;
private volatile Versions.Version version;
private volatile boolean isShutdown = true;
@@ -123,7 +126,7 @@ public abstract class AbstractCluster implements ICluster,
return delegate;
}
- public Wrapper(int generation, Versions.Version version, InstanceConfig config)
+ public Wrapper(int generation, Versions.Version version, IInstanceConfig config)
{
this.generation = generation;
this.config = config;
@@ -134,9 +137,9 @@ public abstract class AbstractCluster implements ICluster,
private IInvokableInstance newInstance(int generation)
{
- ClassLoader classLoader = new InstanceClassLoader(generation, config.num, version.classpath, sharedClassLoader);
- return Instance.transferAdhoc((SerializableBiFunction) Instance::new, classLoader)
- .apply(config.forVersion(version.major), classLoader);
+ ClassLoader classLoader = new InstanceClassLoader(generation, config.num(), version.classpath, sharedClassLoader);
+ return Instance.transferAdhoc((SerializableBiFunction)Instance::new, classLoader)
+ .apply(config.forVersion(version.major), classLoader);
}
public IInstanceConfig config()
@@ -158,7 +161,7 @@ public abstract class AbstractCluster implements ICluster,
public synchronized void startup(ICluster cluster)
{
if (cluster != AbstractCluster.this)
- throw new IllegalArgumentException("Only the owning cluster can be used for startup"); //TODO why have this in the API?
+ throw new IllegalArgumentException("Only the owning cluster can be used for startup");
if (!isShutdown)
throw new IllegalStateException();
delegate().startup(cluster);
@@ -238,7 +241,7 @@ public abstract class AbstractCluster implements ICluster,
}
}
- protected AbstractCluster(File root, Versions.Version initialVersion, List configs,
+ protected AbstractCluster(File root, Versions.Version initialVersion, List configs,
ClassLoader sharedClassLoader)
{
this.root = root;
@@ -248,27 +251,27 @@ public abstract class AbstractCluster implements ICluster,
this.initialVersion = initialVersion;
int generation = AbstractCluster.generation.incrementAndGet();
- for (InstanceConfig config : configs)
+ for (IInstanceConfig config : configs)
{
I instance = newInstanceWrapperInternal(generation, initialVersion, config);
instances.add(instance);
// we use the config().broadcastAddressAndPort() here because we have not initialised the Instance
- I prev = instanceMap.put(instance.broadcastAddressAndPort(), instance);
+ I prev = instanceMap.put(instance.broadcastAddress(), instance);
if (null != prev)
- throw new IllegalStateException("Cluster cannot have multiple nodes with same InetAddressAndPort: " + instance.broadcastAddressAndPort() + " vs " + prev.broadcastAddressAndPort());
+ throw new IllegalStateException("Cluster cannot have multiple nodes with same InetAddressAndPort: " + instance.broadcastAddress() + " vs " + prev.broadcastAddress());
}
this.filters = new MessageFilters();
}
- protected abstract I newInstanceWrapper(int generation, Versions.Version version, InstanceConfig config);
+ protected abstract I newInstanceWrapper(int generation, Versions.Version version, IInstanceConfig config);
- protected I newInstanceWrapperInternal(int generation, Versions.Version version, InstanceConfig config)
+ protected I newInstanceWrapperInternal(int generation, Versions.Version version, IInstanceConfig config)
{
config.validate();
return newInstanceWrapper(generation, version, config);
}
- public I bootstrap(InstanceConfig config)
+ public I bootstrap(IInstanceConfig config)
{
if (!config.has(Feature.GOSSIP) || !config.has(Feature.NETWORK))
throw new IllegalStateException("New nodes can only be bootstrapped when gossip and networking is enabled.");
@@ -276,12 +279,13 @@ public abstract class AbstractCluster implements ICluster,
I instance = newInstanceWrapperInternal(0, initialVersion, config);
instances.add(instance);
- I prev = instanceMap.put(config.broadcastAddressAndPort(), instance);
+
+ I prev = instanceMap.put(config.broadcastAddress(), instance);
if (null != prev)
{
throw new IllegalStateException(String.format("This cluster already contains a node (%d) with with same address and port: %s",
- config.num,
+ config.num(),
instance));
}
@@ -304,7 +308,7 @@ public abstract class AbstractCluster implements ICluster,
return instances.get(node - 1);
}
- public I get(InetAddressAndPort addr)
+ public I get(InetSocketAddress addr)
{
return instanceMap.get(addr);
}
@@ -391,6 +395,11 @@ public abstract class AbstractCluster implements ICluster,
}).run();
}
+ public void schemaChange(String statement, int instance)
+ {
+ get(instance).schemaChangeInternal(statement);
+ }
+
private void updateMessagingVersions()
{
for (IInstance reportTo : instances)
@@ -404,7 +413,7 @@ public abstract class AbstractCluster implements ICluster,
continue;
int minVersion = Math.min(reportFrom.getMessagingVersion(), reportTo.getMessagingVersion());
- reportTo.setMessagingVersion(reportFrom.broadcastAddressAndPort(), minVersion);
+ reportTo.setMessagingVersion(reportFrom.broadcastAddress(), minVersion);
}
}
}
@@ -524,12 +533,7 @@ public abstract class AbstractCluster implements ICluster,
}
}
- public void schemaChange(String statement, int instance)
- {
- get(instance).schemaChangeInternal(statement);
- }
-
- void startup()
+ public void startup()
{
previousHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this::uncaughtExceptions);
@@ -569,257 +573,6 @@ public abstract class AbstractCluster implements ICluster,
get(cl.getInstanceId()).uncaughtException(thread, error);
}
- protected interface Factory>
- {
- C newCluster(File root, Versions.Version version, List configs, ClassLoader sharedClassLoader);
- }
-
- public static class Builder>
- {
- private final Factory factory;
- private int nodeCount;
- private int subnet;
- private Map nodeIdTopology;
- private TokenSupplier tokenSupplier;
- private File root;
- private Versions.Version version = Versions.CURRENT;
- private Consumer configUpdater;
-
- public Builder(Factory factory)
- {
- this.factory = factory;
- }
-
- public Builder withTokenSupplier(TokenSupplier tokenSupplier)
- {
- this.tokenSupplier = tokenSupplier;
- return this;
- }
-
- public Builder withSubnet(int subnet)
- {
- this.subnet = subnet;
- return this;
- }
-
- public Builder withNodes(int nodeCount)
- {
- this.nodeCount = nodeCount;
- return this;
- }
-
- public Builder withDCs(int dcCount)
- {
- return withRacks(dcCount, 1);
- }
-
- public Builder withRacks(int dcCount, int racksPerDC)
- {
- if (nodeCount == 0)
- throw new IllegalStateException("Node count will be calculated. Do not supply total node count in the builder");
-
- int totalRacks = dcCount * racksPerDC;
- int nodesPerRack = (nodeCount + totalRacks - 1) / totalRacks; // round up to next integer
- return withRacks(dcCount, racksPerDC, nodesPerRack);
- }
-
- public Builder withRacks(int dcCount, int racksPerDC, int nodesPerRack)
- {
- if (nodeIdTopology != null)
- throw new IllegalStateException("Network topology already created. Call withDCs/withRacks once or before withDC/withRack calls");
-
- nodeIdTopology = new HashMap<>();
- int nodeId = 1;
- for (int dc = 1; dc <= dcCount; dc++)
- {
- for (int rack = 1; rack <= racksPerDC; rack++)
- {
- for (int rackNodeIdx = 0; rackNodeIdx < nodesPerRack; rackNodeIdx++)
- nodeIdTopology.put(nodeId++, NetworkTopology.dcAndRack(dcName(dc), rackName(rack)));
- }
- }
- // adjust the node count to match the allocatation
- final int adjustedNodeCount = dcCount * racksPerDC * nodesPerRack;
- if (adjustedNodeCount != nodeCount)
- {
- assert adjustedNodeCount > nodeCount : "withRacks should only ever increase the node count";
- logger.info("Network topology of {} DCs with {} racks per DC and {} nodes per rack required increasing total nodes to {}",
- dcCount, racksPerDC, nodesPerRack, adjustedNodeCount);
- nodeCount = adjustedNodeCount;
- }
- return this;
- }
-
- public Builder withDC(String dcName, int nodeCount)
- {
- return withRack(dcName, rackName(1), nodeCount);
- }
-
- public Builder withRack(String dcName, String rackName, int nodesInRack)
- {
- if (nodeIdTopology == null)
- {
- if (nodeCount > 0)
- throw new IllegalStateException("Node count must not be explicitly set, or allocated using withDCs/withRacks");
-
- nodeIdTopology = new HashMap<>();
- }
- for (int nodeId = nodeCount + 1; nodeId <= nodeCount + nodesInRack; nodeId++)
- nodeIdTopology.put(nodeId, NetworkTopology.dcAndRack(dcName, rackName));
-
- nodeCount += nodesInRack;
- return this;
- }
-
- // Map of node ids to dc and rack - must be contiguous with an entry nodeId 1 to nodeCount
- public Builder withNodeIdTopology(Map nodeIdTopology)
- {
- if (nodeIdTopology.isEmpty())
- throw new IllegalStateException("Topology is empty. It must have an entry for every nodeId.");
-
- IntStream.rangeClosed(1, nodeIdTopology.size()).forEach(nodeId -> {
- if (nodeIdTopology.get(nodeId) == null)
- throw new IllegalStateException("Topology is missing entry for nodeId " + nodeId);
- });
-
- if (nodeCount != nodeIdTopology.size())
- {
- nodeCount = nodeIdTopology.size();
- logger.info("Adjusting node count to {} for supplied network topology", nodeCount);
- }
-
- this.nodeIdTopology = new HashMap<>(nodeIdTopology);
-
- return this;
- }
-
- public Builder withRoot(File root)
- {
- this.root = root;
- return this;
- }
-
- public Builder withVersion(Versions.Version version)
- {
- this.version = version;
- return this;
- }
-
- public Builder withConfig(Consumer updater)
- {
- this.configUpdater = updater;
- return this;
- }
-
- public C createWithoutStarting() throws IOException
- {
- if (root == null)
- root = Files.createTempDirectory("dtests").toFile();
-
- if (nodeCount <= 0)
- throw new IllegalStateException("Cluster must have at least one node");
-
- if (nodeIdTopology == null)
- {
- nodeIdTopology = IntStream.rangeClosed(1, nodeCount).boxed()
- .collect(Collectors.toMap(nodeId -> nodeId,
- nodeId -> NetworkTopology.dcAndRack(dcName(0), rackName(0))));
- }
-
- root.mkdirs();
- setupLogging(root);
-
- ClassLoader sharedClassLoader = Thread.currentThread().getContextClassLoader();
-
- List configs = new ArrayList<>();
-
- if (tokenSupplier == null)
- tokenSupplier = evenlyDistributedTokens(nodeCount);
-
- for (int i = 0; i < nodeCount; ++i)
- {
- int nodeNum = i + 1;
- configs.add(createInstanceConfig(nodeNum));
- }
-
- return factory.newCluster(root, version, configs, sharedClassLoader);
- }
-
- public InstanceConfig newInstanceConfig(C cluster)
- {
- return createInstanceConfig(cluster.size() + 1);
- }
-
- private InstanceConfig createInstanceConfig(int nodeNum)
- {
- String ipPrefix = "127.0." + subnet + ".";
- String seedIp = ipPrefix + "1";
- String ipAddress = ipPrefix + nodeNum;
- long token = tokenSupplier.token(nodeNum);
-
- NetworkTopology topology = NetworkTopology.build(ipPrefix, 7012, nodeIdTopology);
-
- InstanceConfig config = InstanceConfig.generate(nodeNum, ipAddress, topology, root, String.valueOf(token), seedIp);
- if (configUpdater != null)
- configUpdater.accept(config);
-
- return config;
- }
-
- public C start() throws IOException
- {
- C cluster = createWithoutStarting();
- cluster.startup();
- return cluster;
- }
- }
-
- public static TokenSupplier evenlyDistributedTokens(int numNodes)
- {
- long increment = (Long.MAX_VALUE / numNodes) * 2;
- return (int nodeId) -> {
- assert nodeId <= numNodes : String.format("Can not allocate a token for a node %s, since only %s nodes are allowed by the token allocation strategy",
- nodeId, numNodes);
- return Long.MIN_VALUE + 1 + nodeId * increment;
- };
- }
-
- public static interface TokenSupplier
- {
- public long token(int nodeId);
- }
-
- static String dcName(int index)
- {
- return "datacenter" + index;
- }
-
- static String rackName(int index)
- {
- return "rack" + index;
- }
-
- private static void setupLogging(File root)
- {
- try
- {
- String testConfPath = "test/conf/logback-dtest.xml";
- Path logConfPath = Paths.get(root.getPath(), "/logback-dtest.xml");
-
- if (!logConfPath.toFile().exists())
- {
- Files.copy(new File(testConfPath).toPath(),
- logConfPath);
- }
-
- System.setProperty("logback.configurationFile", "file://" + logConfPath);
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
- }
-
@Override
public void close()
{
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/Coordinator.java b/test/distributed/org/apache/cassandra/distributed/impl/Coordinator.java
index dee9049db9..c1446d109e 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/Coordinator.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/Coordinator.java
@@ -32,8 +32,9 @@ import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.UntypedResultSet;
import org.apache.cassandra.cql3.statements.SelectStatement;
-import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.apache.cassandra.distributed.api.ICoordinator;
+import org.apache.cassandra.distributed.api.IInstance;
import org.apache.cassandra.distributed.api.QueryResult;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
@@ -53,12 +54,12 @@ public class Coordinator implements ICoordinator
}
@Override
- public QueryResult executeWithResult(String query, Enum> consistencyLevel, Object... boundValues)
+ public QueryResult executeWithResult(String query, ConsistencyLevel consistencyLevel, Object... boundValues)
{
- return instance.sync(() -> executeInternal(query, consistencyLevel, boundValues)).call();
+ return instance().sync(() -> executeInternal(query, consistencyLevel, boundValues)).call();
}
- public Future asyncExecuteWithTracing(UUID sessionId, String query, Enum> consistencyLevelOrigin, Object... boundValues)
+ public Future asyncExecuteWithTracing(UUID sessionId, String query, ConsistencyLevel consistencyLevelOrigin, Object... boundValues)
{
return instance.async(() -> {
try
@@ -73,7 +74,12 @@ public class Coordinator implements ICoordinator
}).call();
}
- private QueryResult executeInternal(String query, Enum> consistencyLevelOrigin, Object[] boundValues)
+ protected org.apache.cassandra.db.ConsistencyLevel toCassandraCL(ConsistencyLevel cl)
+ {
+ return org.apache.cassandra.db.ConsistencyLevel.fromCode(cl.ordinal());
+ }
+
+ private QueryResult executeInternal(String query, ConsistencyLevel consistencyLevelOrigin, Object[] boundValues)
{
ClientState clientState = makeFakeClientState();
CQLStatement prepared = QueryProcessor.getStatement(query, clientState);
@@ -84,7 +90,7 @@ public class Coordinator implements ICoordinator
prepared.validate(QueryState.forInternalCalls().getClientState());
ResultMessage res = prepared.execute(QueryState.forInternalCalls(),
- QueryOptions.create(consistencyLevel,
+ QueryOptions.create(toCassandraCL(consistencyLevel),
boundBBValues,
false,
Integer.MAX_VALUE,
@@ -107,13 +113,18 @@ public class Coordinator implements ICoordinator
}
}
- public Object[][] executeWithTracing(UUID sessionId, String query, Enum> consistencyLevelOrigin, Object... boundValues)
+ public Object[][] executeWithTracing(UUID sessionId, String query, ConsistencyLevel consistencyLevelOrigin, Object... boundValues)
{
return IsolatedExecutor.waitOn(asyncExecuteWithTracing(sessionId, query, consistencyLevelOrigin, boundValues));
}
+ public IInstance instance()
+ {
+ return instance;
+ }
+
@Override
- public Iterator executeWithPaging(String query, Enum> consistencyLevelOrigin, int pageSize, Object... boundValues)
+ public Iterator executeWithPaging(String query, ConsistencyLevel consistencyLevelOrigin, int pageSize, Object... boundValues)
{
if (pageSize <= 0)
throw new IllegalArgumentException("Page size should be strictly positive but was " + pageSize);
@@ -133,7 +144,7 @@ public class Coordinator implements ICoordinator
SelectStatement selectStatement = (SelectStatement) prepared;
- QueryPager pager = selectStatement.getQuery(QueryOptions.create(consistencyLevel,
+ QueryPager pager = selectStatement.getQuery(QueryOptions.create(toCassandraCL(consistencyLevel),
boundBBValues,
false,
pageSize,
@@ -147,7 +158,7 @@ public class Coordinator implements ICoordinator
// Usually pager fetches a single page (see SelectStatement#execute). We need to iterate over all
// of the results lazily.
return new Iterator() {
- Iterator iter = RowUtil.toObjects(UntypedResultSet.create(selectStatement, consistencyLevel, clientState, pager, pageSize));
+ Iterator iter = RowUtil.toObjects(UntypedResultSet.create(selectStatement, toCassandraCL(consistencyLevel), clientState, pager, pageSize));
public boolean hasNext()
{
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/DelegatingInvokableInstance.java b/test/distributed/org/apache/cassandra/distributed/impl/DelegatingInvokableInstance.java
index 72949447eb..2f7a043a71 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/DelegatingInvokableInstance.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/DelegatingInvokableInstance.java
@@ -19,6 +19,7 @@
package org.apache.cassandra.distributed.impl;
import java.io.Serializable;
+import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;
@@ -29,9 +30,10 @@ import java.util.function.Function;
import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.distributed.api.ICoordinator;
import org.apache.cassandra.distributed.api.IInstanceConfig;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.api.IListen;
import org.apache.cassandra.distributed.api.IMessage;
-import org.apache.cassandra.locator.InetAddressAndPort;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
public abstract class DelegatingInvokableInstance implements IInvokableInstance
{
@@ -44,9 +46,9 @@ public abstract class DelegatingInvokableInstance implements IInvokableInstance
}
@Override
- public InetAddressAndPort broadcastAddressAndPort()
+ public InetSocketAddress broadcastAddress()
{
- return delegate().broadcastAddressAndPort();
+ return delegate().broadcastAddress();
}
@Override
@@ -80,7 +82,7 @@ public abstract class DelegatingInvokableInstance implements IInvokableInstance
}
@Override
- public void setMessagingVersion(InetAddressAndPort endpoint, int version)
+ public void setMessagingVersion(InetSocketAddress endpoint, int version)
{
delegate().setMessagingVersion(endpoint, version);
}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/DistributedTestSnitch.java b/test/distributed/org/apache/cassandra/distributed/impl/DistributedTestSnitch.java
index 736e77bb27..e671f4d9bc 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/DistributedTestSnitch.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/DistributedTestSnitch.java
@@ -19,10 +19,13 @@
package org.apache.cassandra.distributed.impl;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.cassandra.config.Config;
import org.apache.cassandra.db.SystemKeyspace;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
import org.apache.cassandra.gms.ApplicationState;
import org.apache.cassandra.gms.EndpointState;
import org.apache.cassandra.gms.Gossiper;
@@ -34,6 +37,30 @@ import org.apache.cassandra.utils.FBUtilities;
public class DistributedTestSnitch extends AbstractNetworkTopologySnitch
{
private static NetworkTopology mapping = null;
+ private static final Map cache = new ConcurrentHashMap<>();
+ private static final Map cacheInverse = new ConcurrentHashMap<>();
+
+ static InetAddressAndPort toCassandraInetAddressAndPort(InetSocketAddress addressAndPort)
+ {
+ InetAddressAndPort m = cacheInverse.get(addressAndPort);
+ if (m == null)
+ {
+ m = InetAddressAndPort.getByAddressOverrideDefaults(addressAndPort.getAddress(), addressAndPort.getPort());
+ cache.put(m, addressAndPort);
+ }
+ return m;
+ }
+
+ static InetSocketAddress fromCassandraInetAddressAndPort(InetAddressAndPort addressAndPort)
+ {
+ InetSocketAddress m = cache.get(addressAndPort);
+ if (m == null)
+ {
+ m = NetworkTopology.addressAndPort(addressAndPort.address, addressAndPort.port);
+ cache.put(addressAndPort, m);
+ }
+ return m;
+ }
private Map> savedEndpoints;
private static final String DEFAULT_DC = "UNKNOWN_DC";
@@ -48,7 +75,7 @@ public class DistributedTestSnitch extends AbstractNetworkTopologySnitch
public String getRack(InetAddressAndPort endpoint)
{
assert mapping != null : "network topology must be assigned before using snitch";
- return maybeGetFromEndpointState(mapping.localRack(endpoint), endpoint, ApplicationState.RACK, DEFAULT_RACK);
+ return maybeGetFromEndpointState(mapping.localRack(fromCassandraInetAddressAndPort(endpoint)), endpoint, ApplicationState.RACK, DEFAULT_RACK);
}
public String getDatacenter(InetAddress endpoint)
@@ -60,7 +87,7 @@ public class DistributedTestSnitch extends AbstractNetworkTopologySnitch
public String getDatacenter(InetAddressAndPort endpoint)
{
assert mapping != null : "network topology must be assigned before using snitch";
- return maybeGetFromEndpointState(mapping.localDC(endpoint), endpoint, ApplicationState.DC, DEFAULT_DC);
+ return maybeGetFromEndpointState(mapping.localDC(fromCassandraInetAddressAndPort(endpoint)), endpoint, ApplicationState.DC, DEFAULT_DC);
}
// Here, the logic is slightly different from what we have in GossipingPropertyFileSnitch since we have a different
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/IInvokableInstance.java b/test/distributed/org/apache/cassandra/distributed/impl/IInvokableInstance.java
deleted file mode 100644
index d0f8a5f9f0..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/IInvokableInstance.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import java.io.Serializable;
-import java.util.concurrent.Future;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import org.apache.cassandra.distributed.api.IInstance;
-
-/**
- * This version is only supported for a Cluster running the same code as the test environment, and permits
- * ergonomic cross-node behaviours, without editing the cross-version API.
- *
- * A lambda can be written tto be invoked on any or all of the nodes.
- *
- * The reason this cannot (easily) be made cross-version is that the lambda is tied to the declaring class, which will
- * not be the same in the alternate version. Even were it not, there would likely be a runtime linkage error given
- * any code divergence.
- */
-public interface IInvokableInstance extends IInstance
-{
- public default CallableNoExcept> asyncCallsOnInstance(SerializableCallable call) { return async(transfer(call)); }
- public default CallableNoExcept callsOnInstance(SerializableCallable call) { return sync(transfer(call)); }
- public default O callOnInstance(SerializableCallable call) { return callsOnInstance(call).call(); }
-
- public default CallableNoExcept> asyncRunsOnInstance(SerializableRunnable run) { return async(transfer(run)); }
- public default Runnable runsOnInstance(SerializableRunnable run) { return sync(transfer(run)); }
- public default void runOnInstance(SerializableRunnable run) { runsOnInstance(run).run(); }
-
- public default Function> asyncAcceptsOnInstance(SerializableConsumer consumer) { return async(transfer(consumer)); }
- public default Consumer acceptsOnInstance(SerializableConsumer consumer) { return sync(transfer(consumer)); }
-
- public default BiFunction> asyncAcceptsOnInstance(SerializableBiConsumer consumer) { return async(transfer(consumer)); }
- public default BiConsumer acceptsOnInstance(SerializableBiConsumer consumer) { return sync(transfer(consumer)); }
-
- public default Function> asyncAppliesOnInstance(SerializableFunction f) { return async(transfer(f)); }
- public default Function appliesOnInstance(SerializableFunction f) { return sync(transfer(f)); }
-
- public default BiFunction> asyncAppliesOnInstance(SerializableBiFunction f) { return async(transfer(f)); }
- public default BiFunction appliesOnInstance(SerializableBiFunction f) { return sync(transfer(f)); }
-
- public default TriFunction> asyncAppliesOnInstance(SerializableTriFunction f) { return async(transfer(f)); }
- public default TriFunction appliesOnInstance(SerializableTriFunction f) { return sync(transfer(f)); }
-
- public E transfer(E object);
-
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/IUpgradeableInstance.java b/test/distributed/org/apache/cassandra/distributed/impl/IUpgradeableInstance.java
deleted file mode 100644
index 3eb3657d4d..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/IUpgradeableInstance.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import org.apache.cassandra.distributed.api.IInstance;
-
-// this lives outside the api package so that we do not have to worry about inter-version compatibility
-public interface IUpgradeableInstance extends IInstance
-{
- // only to be invoked while the node is shutdown!
- public void setVersion(Versions.Version version);
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java
index 90d747ef9d..e79a182dfe 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java
@@ -20,15 +20,21 @@ package org.apache.cassandra.distributed.impl;
import java.io.File;
import java.io.IOException;
+import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
import javax.management.ListenerNotFoundException;
import javax.management.Notification;
import javax.management.NotificationListener;
@@ -59,11 +65,13 @@ import org.apache.cassandra.dht.Token;
import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.distributed.api.ICoordinator;
import org.apache.cassandra.distributed.api.IInstanceConfig;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.api.IListen;
import org.apache.cassandra.distributed.api.IMessage;
import org.apache.cassandra.distributed.api.NodeToolResult;
import org.apache.cassandra.distributed.mock.nodetool.InternalNodeProbe;
import org.apache.cassandra.distributed.mock.nodetool.InternalNodeProbeFactory;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
import org.apache.cassandra.gms.ApplicationState;
import org.apache.cassandra.gms.Gossiper;
import org.apache.cassandra.gms.VersionedValue;
@@ -105,9 +113,18 @@ import static java.util.concurrent.TimeUnit.MINUTES;
import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
import static org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL;
import static org.apache.cassandra.distributed.api.Feature.NETWORK;
+import static org.apache.cassandra.distributed.impl.DistributedTestSnitch.fromCassandraInetAddressAndPort;
+import static org.apache.cassandra.distributed.impl.DistributedTestSnitch.toCassandraInetAddressAndPort;
public class Instance extends IsolatedExecutor implements IInvokableInstance
{
+ private static final Map, Function> mapper = new HashMap, Function>() {{
+ this.put(IInstanceConfig.ParameterizedClass.class, (obj) -> {
+ IInstanceConfig.ParameterizedClass pc = (IInstanceConfig.ParameterizedClass) obj;
+ return new org.apache.cassandra.config.ParameterizedClass(pc.class_name, pc.parameters);
+ });
+ }};
+
public final IInstanceConfig config;
// should never be invoked directly, so that it is instantiated on other class loader;
@@ -117,7 +134,9 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
super("node" + config.num(), classLoader);
this.config = config;
InstanceIDDefiner.setInstanceId(config.num());
- FBUtilities.setBroadcastInetAddressAndPort(config.broadcastAddressAndPort());
+ FBUtilities.setBroadcastInetAddressAndPort(InetAddressAndPort.getByAddressOverrideDefaults(config.broadcastAddress().getAddress(),
+ config.broadcastAddress().getPort()));
+
// Set the config at instance creation, possibly before startup() has run on all other instances.
// setMessagingVersions below will call runOnInstance which will instantiate
// the MessagingService and dependencies preventing later changes to network parameters.
@@ -146,7 +165,7 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
}
@Override
- public InetAddressAndPort broadcastAddressAndPort() { return config.broadcastAddressAndPort(); }
+ public InetSocketAddress broadcastAddress() { return config.broadcastAddress(); }
@Override
public Object[][] executeInternal(String query, Object... args)
@@ -206,36 +225,30 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
private void registerMockMessaging(ICluster cluster)
{
MessagingService.instance().outboundSink.add((message, to) -> {
- cluster.get(to).receiveMessage(serializeMessage(message.from(), to, message));
+ InetSocketAddress toAddr = fromCassandraInetAddressAndPort(to);
+ cluster.get(toAddr).receiveMessage(serializeMessage(message.from(), to, message));
return false;
});
}
private void registerInboundFilter(ICluster cluster)
{
- MessagingService.instance().inboundSink.add(message ->
- permitMessageInbound(cluster, serializeMessage(message.from(), broadcastAddressAndPort(), message)));
+ MessagingService.instance().inboundSink.add(message -> {
+ IMessage serialized = serializeMessage(message.from(), toCassandraInetAddressAndPort(broadcastAddress()), message);
+ int fromNum = cluster.get(serialized.from()).config().num();
+ int toNum = config.num(); // since this instance is reciving the message, to will always be this instance
+ return cluster.filters().permitInbound(fromNum, toNum, serialized);
+ });
}
private void registerOutboundFilter(ICluster cluster)
{
-
- MessagingService.instance().outboundSink.add((message, to) ->
- permitMessageOutbound(cluster, to, serializeMessage(message.from(), to, message)));
- }
-
- private boolean permitMessageInbound(ICluster cluster, IMessage message)
- {
- int fromNum = cluster.get(message.from()).config().num();
- int toNum = config.num(); // since this instance is reciving the message, to will always be this instance
- return cluster.filters().permitInbound(fromNum, toNum, message);
- }
-
- private boolean permitMessageOutbound(ICluster cluster, InetAddressAndPort to, IMessage message)
- {
- int fromNum = config.num(); // since this instance is sending the message, from will always be this instance
- int toNum = cluster.get(to).config().num();
- return cluster.filters().permitOutbound(fromNum, toNum, message);
+ MessagingService.instance().outboundSink.add((message, to) -> {
+ IMessage serialzied = serializeMessage(message.from(), to, message);
+ int fromNum = config.num(); // since this instance is sending the message, from will always be this instance
+ int toNum = cluster.get(fromCassandraInetAddressAndPort(to)).config().num();
+ return cluster.filters().permitOutbound(fromNum, toNum, serialzied);
+ });
}
public void uncaughtException(Thread thread, Throwable throwable)
@@ -249,7 +262,7 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
{
int version = MessagingService.instance().versions.get(to);
Message.serializer.serialize(messageOut, out, version);
- return new MessageImpl(messageOut.verb().id, out.toByteArray(), messageOut.id(), version, from);
+ return new MessageImpl(messageOut.verb().id, out.toByteArray(), messageOut.id(), version, fromCassandraInetAddressAndPort(from));
}
catch (IOException e)
{
@@ -262,7 +275,7 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
{
try (DataInputBuffer in = new DataInputBuffer(message.bytes()))
{
- return Message.serializer.deserialize(in, message.from(), message.version());
+ return Message.serializer.deserialize(in, toCassandraInetAddressAndPort(message.from()), message.version());
}
catch (Throwable t)
{
@@ -286,9 +299,8 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
Message.Header header = messageIn.header;
TraceState state = Tracing.instance.initializeFromMessage(header);
if (state != null) state.trace("{} message received from {}", header.verb, header.from);
- header.verb.stage.execute(() -> {
- MessagingService.instance().inboundSink.accept(messageIn);
- }, ExecutorLocals.create(state));
+ header.verb.stage.execute(() -> MessagingService.instance().inboundSink.accept(messageIn),
+ ExecutorLocals.create(state));
}).run();
}
@@ -297,9 +309,10 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
return callsOnInstance(() -> MessagingService.current_version).call();
}
- public void setMessagingVersion(InetAddressAndPort endpoint, int version)
+ @Override
+ public void setMessagingVersion(InetSocketAddress endpoint, int version)
{
- MessagingService.instance().versions.set(endpoint, version);
+ MessagingService.instance().versions.set(toCassandraInetAddressAndPort(endpoint), version);
}
public void flush(String keyspace)
@@ -339,7 +352,8 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
mkdirs();
- assert config.networkTopology().contains(config.broadcastAddressAndPort());
+ assert config.networkTopology().contains(config.broadcastAddress()) : String.format("Network topology %s doesn't contain the address %s",
+ config.networkTopology(), config.broadcastAddress());
DistributedTestSnitch.assign(config.networkTopology());
DatabaseDescriptor.daemonInitialization();
@@ -386,6 +400,7 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
}
registerInboundFilter(cluster);
registerOutboundFilter(cluster);
+
JVMStabilityInspector.replaceKiller(new InstanceKiller());
// TODO: this is more than just gossip
@@ -393,6 +408,7 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
{
StorageService.instance.initServer();
StorageService.instance.removeShutdownHook();
+ Gossiper.waitToSettle();
}
else
{
@@ -413,8 +429,9 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
StorageService.instance.setRpcReady(true);
}
- if (!FBUtilities.getBroadcastAddressAndPort().equals(broadcastAddressAndPort()))
- throw new IllegalStateException();
+ if (!FBUtilities.getBroadcastAddressAndPort().address.equals(broadcastAddress().getAddress()) ||
+ FBUtilities.getBroadcastAddressAndPort().port != broadcastAddress().getPort())
+ throw new IllegalStateException(String.format("%s != %s", FBUtilities.getBroadcastAddressAndPort(), broadcastAddress()));
ActiveRepairService.instance.start();
}
@@ -436,10 +453,10 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
new File(dir).mkdirs();
}
- private static Config loadConfig(IInstanceConfig overrides)
+ private Config loadConfig(IInstanceConfig overrides)
{
Config config = new Config();
- overrides.propagate(config);
+ overrides.propagate(config, mapper);
return config;
}
@@ -448,13 +465,13 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
// This should be done outside instance in order to avoid serializing config
String partitionerName = config.getString("partitioner");
List initialTokens = new ArrayList<>();
- List hosts = new ArrayList<>();
+ List hosts = new ArrayList<>();
List hostIds = new ArrayList<>();
for (int i = 1 ; i <= cluster.size() ; ++i)
{
IInstanceConfig config = cluster.get(i).config();
initialTokens.add(config.getString("initial_token"));
- hosts.add(config.broadcastAddressAndPort());
+ hosts.add(config.broadcastAddress());
hostIds.add(config.hostId());
}
@@ -468,32 +485,33 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
for (int i = 0; i < tokens.size(); i++)
{
- InetAddressAndPort ep = hosts.get(i);
+ InetSocketAddress ep = hosts.get(i);
+ InetAddressAndPort addressAndPort = toCassandraInetAddressAndPort(ep);
UUID hostId = hostIds.get(i);
Token token = tokens.get(i);
Gossiper.runInGossipStageBlocking(() -> {
- Gossiper.instance.initializeNodeUnsafe(ep, hostId, 1);
- Gossiper.instance.injectApplicationState(ep,
+ Gossiper.instance.initializeNodeUnsafe(addressAndPort, hostId, 1);
+ Gossiper.instance.injectApplicationState(addressAndPort,
ApplicationState.TOKENS,
new VersionedValue.VersionedValueFactory(partitioner).tokens(Collections.singleton(token)));
- storageService.onChange(ep,
+ storageService.onChange(addressAndPort,
ApplicationState.STATUS_WITH_PORT,
new VersionedValue.VersionedValueFactory(partitioner).normal(Collections.singleton(token)));
- storageService.onChange(ep,
+ storageService.onChange(addressAndPort,
ApplicationState.STATUS,
new VersionedValue.VersionedValueFactory(partitioner).normal(Collections.singleton(token)));
- Gossiper.instance.realMarkAlive(ep, Gossiper.instance.getEndpointStateForEndpoint(ep));
+ Gossiper.instance.realMarkAlive(addressAndPort, Gossiper.instance.getEndpointStateForEndpoint(addressAndPort));
});
int messagingVersion = cluster.get(ep).isShutdown()
? MessagingService.current_version
: Math.min(MessagingService.current_version, cluster.get(ep).getMessagingVersion());
- MessagingService.instance().versions.set(ep, messagingVersion);
+ MessagingService.instance().versions.set(addressAndPort, messagingVersion);
}
// check that all nodes are in token metadata
for (int i = 0; i < tokens.size(); ++i)
- assert storageService.getTokenMetadata().isMember(hosts.get(i));
+ assert storageService.getTokenMetadata().isMember(toCassandraInetAddressAndPort(hosts.get(i)));
}
catch (Throwable e) // UnknownHostException
{
@@ -621,8 +639,9 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
}
}
- private static final class CollectingNotificationListener implements NotificationListener {
- private final CopyOnWriteArrayList notifications = new CopyOnWriteArrayList<>();
+ private static final class CollectingNotificationListener implements NotificationListener
+ {
+ private final List notifications = new CopyOnWriteArrayList<>();
public void handleNotification(Notification notification, Object handback)
{
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/InstanceClassLoader.java b/test/distributed/org/apache/cassandra/distributed/impl/InstanceClassLoader.java
deleted file mode 100644
index 75a8912c5e..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/InstanceClassLoader.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import com.google.common.base.Predicate;
-import org.apache.cassandra.config.ParameterizedClass;
-import org.apache.cassandra.io.util.DataOutputPlus;
-import org.apache.cassandra.io.util.Memory;
-import org.apache.cassandra.locator.InetAddressAndPort;
-import org.apache.cassandra.utils.Pair;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class InstanceClassLoader extends URLClassLoader
-{
- // Classes that have to be shared between instances, for configuration or returning values
- private static final Set sharedClassNames = Arrays.stream(new Class[]
- {
- Pair.class,
- InetAddressAndPort.class,
- ParameterizedClass.class,
- IInvokableInstance.class,
- NetworkTopology.class
- })
- .map(Class::getName)
- .collect(Collectors.toSet());
-
- private static final Predicate sharePackage = name ->
- name.startsWith("org.apache.cassandra.distributed.api.")
- || name.startsWith("sun.")
- || name.startsWith("oracle.")
- || name.startsWith("com.intellij.")
- || name.startsWith("com.sun.")
- || name.startsWith("com.oracle.")
- || name.startsWith("java.")
- || name.startsWith("javax.")
- || name.startsWith("jdk.")
- || name.startsWith("netscape.")
- || name.startsWith("org.xml.sax.");
-
- private static final Predicate shareClass = name -> sharePackage.apply(name) || sharedClassNames.contains(name);
-
- public static interface Factory
- {
- InstanceClassLoader create(int id, URL[] urls, ClassLoader sharedClassLoader);
- }
-
- private volatile boolean isClosed = false;
- private final URL[] urls;
- private final int generation; // used to help debug class loader leaks, by helping determine which classloaders should have been collected
- private final int id;
- private final ClassLoader sharedClassLoader;
-
- InstanceClassLoader(int generation, int id, URL[] urls, ClassLoader sharedClassLoader)
- {
- super(urls, null);
- this.urls = urls;
- this.sharedClassLoader = sharedClassLoader;
- this.generation = generation;
- this.id = id;
- }
-
- public int getClusterGeneration()
- {
- return generation;
- }
-
- public int getInstanceId()
- {
- return id;
- }
-
- @Override
- public Class> loadClass(String name) throws ClassNotFoundException
- {
- if (shareClass.apply(name))
- return sharedClassLoader.loadClass(name);
-
- return loadClassInternal(name);
- }
-
- Class> loadClassInternal(String name) throws ClassNotFoundException
- {
- if (isClosed)
- throw new IllegalStateException(String.format("Can't load %s. Instance class loader is already closed.", name));
-
- synchronized (getClassLoadingLock(name))
- {
- // First, check if the class has already been loaded
- Class> c = findLoadedClass(name);
-
- if (c == null)
- c = findClass(name);
-
- return c;
- }
- }
-
- /**
- * @return true iff this class was loaded by an InstanceClassLoader, and as such is used by a dtest node
- */
- public static boolean wasLoadedByAnInstanceClassLoader(Class> clazz)
- {
- return clazz.getClassLoader().getClass().getName().equals(InstanceClassLoader.class.getName());
- }
-
- public String toString()
- {
- return "InstanceClassLoader{" +
- "generation=" + generation +
- ", id = " + id +
- ", urls=" + Arrays.toString(urls) +
- '}';
- }
-
- public void close() throws IOException
- {
- isClosed = true;
- super.close();
- }
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java b/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java
index ad4f6bfb93..9e2d9d633c 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java
@@ -18,16 +18,9 @@
package org.apache.cassandra.distributed.impl;
-import org.apache.cassandra.config.Config;
-import org.apache.cassandra.config.ParameterizedClass;
-import org.apache.cassandra.distributed.api.Feature;
-import org.apache.cassandra.distributed.api.IInstanceConfig;
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.locator.InetAddressAndPort;
-import org.apache.cassandra.locator.SimpleSeedProvider;
-
import java.io.File;
import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
@@ -35,6 +28,14 @@ import java.util.EnumSet;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
+import java.util.function.Function;
+
+import org.apache.cassandra.distributed.api.Feature;
+import org.apache.cassandra.distributed.api.IInstanceConfig;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
+import org.apache.cassandra.distributed.shared.Versions;
+import org.apache.cassandra.locator.InetAddressAndPort;
+import org.apache.cassandra.locator.SimpleSeedProvider;
public class InstanceConfig implements IInstanceConfig
{
@@ -54,28 +55,6 @@ public class InstanceConfig implements IInstanceConfig
private volatile InetAddressAndPort broadcastAddressAndPort;
- @Override
- public InetAddressAndPort broadcastAddressAndPort()
- {
- if (broadcastAddressAndPort == null)
- {
- broadcastAddressAndPort = getAddressAndPortFromConfig("broadcast_address", "storage_port");
- }
- return broadcastAddressAndPort;
- }
-
- private InetAddressAndPort getAddressAndPortFromConfig(String addressProp, String portProp)
- {
- try
- {
- return InetAddressAndPort.getByNameOverrideDefaults(getString(addressProp), getInt(portProp));
- }
- catch (UnknownHostException e)
- {
- throw new IllegalStateException(e);
- }
- }
-
private InstanceConfig(int num,
NetworkTopology networkTopology,
String broadcast_address,
@@ -117,7 +96,7 @@ public class InstanceConfig implements IInstanceConfig
.set("storage_port", 7012)
.set("endpoint_snitch", DistributedTestSnitch.class.getName())
.set("seed_provider", new ParameterizedClass(SimpleSeedProvider.class.getName(),
- Collections.singletonMap("seeds", seedIp + ":7012")))
+ Collections.singletonMap("seeds", seedIp + ":7012")))
// required settings for dtest functionality
.set("diagnostic_events_enabled", true)
.set("auto_bootstrap", false)
@@ -140,6 +119,44 @@ public class InstanceConfig implements IInstanceConfig
this.broadcastAddressAndPort = copy.broadcastAddressAndPort;
}
+
+ @Override
+ public InetSocketAddress broadcastAddress()
+ {
+ return DistributedTestSnitch.fromCassandraInetAddressAndPort(getBroadcastAddressAndPort());
+ }
+
+ protected InetAddressAndPort getBroadcastAddressAndPort()
+ {
+ if (broadcastAddressAndPort == null)
+ {
+ broadcastAddressAndPort = getAddressAndPortFromConfig("broadcast_address", "storage_port");
+ }
+ return broadcastAddressAndPort;
+ }
+
+ private InetAddressAndPort getAddressAndPortFromConfig(String addressProp, String portProp)
+ {
+ try
+ {
+ return InetAddressAndPort.getByNameOverrideDefaults(getString(addressProp), getInt(portProp));
+ }
+ catch (UnknownHostException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public String localRack()
+ {
+ return networkTopology().localRack(broadcastAddress());
+ }
+
+ public String localDatacenter()
+ {
+ return networkTopology().localDC(broadcastAddress());
+ }
+
public InstanceConfig with(Feature featureFlag)
{
featureFlags.add(featureFlag);
@@ -163,8 +180,6 @@ public class InstanceConfig implements IInstanceConfig
if (value == null)
value = NULL;
- // test value
- propagate(new Config(), fieldName, value, false);
params.put(fieldName, value);
return this;
}
@@ -179,16 +194,10 @@ public class InstanceConfig implements IInstanceConfig
return this;
}
- public void propagateIfSet(Object writeToConfig, String fieldName)
- {
- if (params.containsKey(fieldName))
- propagate(writeToConfig, fieldName, params.get(fieldName), true);
- }
-
- public void propagate(Object writeToConfig)
+ public void propagate(Object writeToConfig, Map, Function> mapping)
{
for (Map.Entry e : params.entrySet())
- propagate(writeToConfig, e.getKey(), e.getValue(), true);
+ propagate(writeToConfig, e.getKey(), e.getValue(), mapping);
}
public void validate()
@@ -197,11 +206,14 @@ public class InstanceConfig implements IInstanceConfig
throw new IllegalArgumentException("In-JVM dtests do not support vnodes as of now.");
}
- private void propagate(Object writeToConfig, String fieldName, Object value, boolean ignoreMissing)
+ private void propagate(Object writeToConfig, String fieldName, Object value, Map, Function> mapping)
{
if (value == NULL)
value = null;
+ if (mapping != null && mapping.containsKey(value.getClass()))
+ value = mapping.get(value.getClass()).apply(value);
+
Class> configClass = writeToConfig.getClass();
Field valueField;
try
@@ -210,9 +222,7 @@ public class InstanceConfig implements IInstanceConfig
}
catch (NoSuchFieldException e)
{
- if (!ignoreMissing)
- throw new IllegalStateException(e);
- return;
+ throw new IllegalStateException(e);
}
if (valueField.getType().isEnum() && value instanceof String)
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedExecutor.java b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedExecutor.java
index 248155a7e2..fc31fdf978 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedExecutor.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedExecutor.java
@@ -39,6 +39,7 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Supplier;
import org.slf4j.LoggerFactory;
@@ -101,6 +102,9 @@ public class IsolatedExecutor implements IIsolatedExecutor
});
}
+ public Supplier> supplyAsync(SerializableSupplier call) { return () -> isolatedExecutor.submit(call::get); }
+ public Supplier supplySync(SerializableSupplier call) { return () -> waitOn(supplyAsync(call).get()); }
+
public CallableNoExcept> async(CallableNoExcept call) { return () -> isolatedExecutor.submit(call); }
public CallableNoExcept sync(CallableNoExcept call) { return () -> waitOn(async(call).call()); }
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/MessageFilters.java b/test/distributed/org/apache/cassandra/distributed/impl/MessageFilters.java
deleted file mode 100644
index b4017e1b70..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/MessageFilters.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.cassandra.distributed.api.IMessage;
-import org.apache.cassandra.distributed.api.IMessageFilters;
-
-public class MessageFilters implements IMessageFilters
-{
- private final List inboundFilters = new CopyOnWriteArrayList<>();
- private final List outboundFilters = new CopyOnWriteArrayList<>();
-
- public boolean permitInbound(int from, int to, IMessage msg)
- {
- return permit(inboundFilters, from, to, msg);
- }
-
- public boolean permitOutbound(int from, int to, IMessage msg)
- {
- return permit(outboundFilters, from, to, msg);
- }
-
- private static boolean permit(List filters, int from, int to, IMessage msg)
- {
- for (Filter filter : filters)
- {
- if (filter.matches(from, to, msg))
- return false;
- }
- return true;
- }
-
- public static class Filter implements IMessageFilters.Filter
- {
- final List parent;
- final int[] from;
- final int[] to;
- final int[] verbs;
- final Matcher matcher;
-
- private Filter(List parent, int[] from, int[] to, int[] verbs, Matcher matcher)
- {
- if (from != null)
- {
- from = from.clone();
- Arrays.sort(from);
- }
- if (to != null)
- {
- to = to.clone();
- Arrays.sort(to);
- }
- if (verbs != null)
- {
- verbs = verbs.clone();
- Arrays.sort(verbs);
- }
- this.parent = Objects.requireNonNull(parent, "parent");
- this.from = from;
- this.to = to;
- this.verbs = verbs;
- this.matcher = matcher;
- }
-
- public int hashCode()
- {
- return (from == null ? 0 : Arrays.hashCode(from))
- + (to == null ? 0 : Arrays.hashCode(to))
- + (verbs == null ? 0 : Arrays.hashCode(verbs)
- + parent.hashCode());
- }
-
- public boolean equals(Object that)
- {
- return that instanceof Filter && equals((Filter) that);
- }
-
- public boolean equals(Filter that)
- {
- return Arrays.equals(from, that.from)
- && Arrays.equals(to, that.to)
- && Arrays.equals(verbs, that.verbs)
- && parent.equals(that.parent);
- }
-
- public Filter off()
- {
- parent.remove(this);
- return this;
- }
-
- public Filter on()
- {
- parent.add(this);
- return this;
- }
-
- public boolean matches(int from, int to, IMessage msg)
- {
- return (this.from == null || Arrays.binarySearch(this.from, from) >= 0)
- && (this.to == null || Arrays.binarySearch(this.to, to) >= 0)
- && (this.verbs == null || Arrays.binarySearch(this.verbs, msg.verb()) >= 0)
- && (this.matcher == null || this.matcher.matches(from, to, msg));
- }
- }
-
- public class Builder implements IMessageFilters.Builder
- {
- boolean inbound;
- int[] from;
- int[] to;
- int[] verbs;
- Matcher matcher;
-
- private Builder(boolean inbound)
- {
- this.inbound = inbound;
- }
-
- public IMessageFilters.Builder from(int... nums)
- {
- from = nums;
- return this;
- }
-
- public IMessageFilters.Builder to(int... nums)
- {
- to = nums;
- return this;
- }
-
- public IMessageFilters.Builder verbs(int... verbs)
- {
- this.verbs = verbs;
- return this;
- }
-
- public IMessageFilters.Builder allVerbs()
- {
- this.verbs = null;
- return this;
- }
-
- public IMessageFilters.Builder inbound(boolean inbound)
- {
- this.inbound = inbound;
- return this;
- }
-
- public IMessageFilters.Builder messagesMatching(Matcher matcher)
- {
- this.matcher = matcher;
- return this;
- }
-
- public IMessageFilters.Filter drop()
- {
- return new Filter(inbound ? inboundFilters : outboundFilters, from, to, verbs, matcher).on();
- }
- }
-
-
- public IMessageFilters.Builder inbound(boolean inbound)
- {
- return new Builder(inbound);
- }
-
- @Override
- public void reset()
- {
- inboundFilters.clear();
- outboundFilters.clear();
- }
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/MessageImpl.java b/test/distributed/org/apache/cassandra/distributed/impl/MessageImpl.java
index e5c72c5438..ebc31b1225 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/MessageImpl.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/MessageImpl.java
@@ -18,8 +18,10 @@
package org.apache.cassandra.distributed.impl;
+import java.net.InetSocketAddress;
+
import org.apache.cassandra.distributed.api.IMessage;
-import org.apache.cassandra.locator.InetAddressAndPort;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
// a container for simplifying the method signature for per-instance message handling/delivery
public class MessageImpl implements IMessage
@@ -28,9 +30,9 @@ public class MessageImpl implements IMessage
public final byte[] bytes;
public final long id;
public final int version;
- public final InetAddressAndPort from;
+ public final InetSocketAddress from;
- public MessageImpl(int verb, byte[] bytes, long id, int version, InetAddressAndPort from)
+ public MessageImpl(int verb, byte[] bytes, long id, int version, InetSocketAddress from)
{
this.verb = verb;
this.bytes = bytes;
@@ -59,7 +61,7 @@ public class MessageImpl implements IMessage
return version;
}
- public InetAddressAndPort from()
+ public InetSocketAddress from()
{
return from;
}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/NetworkTopology.java b/test/distributed/org/apache/cassandra/distributed/impl/NetworkTopology.java
deleted file mode 100644
index f7c31ff2c8..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/NetworkTopology.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.IntFunction;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.locator.InetAddressAndPort;
-import org.apache.cassandra.utils.Pair;
-
-public class NetworkTopology
-{
- private final Map map;
-
- public static class DcAndRack
- {
- private final String dc;
- private final String rack;
-
- private DcAndRack(String dc, String rack)
- {
- this.dc = dc;
- this.rack = rack;
- }
- }
-
- public static DcAndRack dcAndRack(String dc, String rack)
- {
- return new DcAndRack(dc, rack);
- }
-
- private NetworkTopology() {
- map = new HashMap<>();
- }
-
- @SuppressWarnings("WeakerAccess")
- public NetworkTopology(NetworkTopology networkTopology)
- {
- map = new HashMap<>(networkTopology.map);
- }
-
- public static NetworkTopology build(String ipPrefix, int broadcastPort, Map nodeIdTopology)
- {
- final NetworkTopology topology = new NetworkTopology();
-
- for (int nodeId = 1; nodeId <= nodeIdTopology.size(); nodeId++)
- {
- String broadcastAddress = ipPrefix + nodeId;
-
- try
- {
- DcAndRack dcAndRack = nodeIdTopology.get(nodeId);
- if (dcAndRack == null)
- throw new IllegalStateException("nodeId " + nodeId + "not found in instanceMap");
-
- InetAddressAndPort broadcastAddressAndPort = InetAddressAndPort.getByAddressOverrideDefaults(
- InetAddress.getByName(broadcastAddress), broadcastPort);
- topology.put(broadcastAddressAndPort, dcAndRack);
- }
- catch (UnknownHostException e)
- {
- throw new ConfigurationException("Unknown broadcast_address '" + broadcastAddress + '\'', false);
- }
- }
- return topology;
- }
-
- public DcAndRack put(InetAddressAndPort key, DcAndRack value)
- {
- return map.put(key, value);
- }
-
- public String localRack(InetAddressAndPort key)
- {
- DcAndRack p = map.get(key);
- if (p == null)
- return null;
- return p.rack;
- }
-
- public String localDC(InetAddressAndPort key)
- {
- DcAndRack p = map.get(key);
- if (p == null)
- return null;
- return p.dc;
- }
-
- public boolean contains(InetAddressAndPort key)
- {
- return map.containsKey(key);
- }
-
- public String toString()
- {
- return "NetworkTopology{" + map + '}';
- }
-
-
- public static Map singleDcNetworkTopology(int nodeCount,
- String dc,
- String rack)
- {
- return networkTopology(nodeCount, (nodeid) -> NetworkTopology.dcAndRack(dc, rack));
- }
-
- public static Map networkTopology(int nodeCount,
- IntFunction dcAndRackSupplier)
- {
-
- return IntStream.rangeClosed(1, nodeCount).boxed()
- .collect(Collectors.toMap(nodeId -> nodeId,
- dcAndRackSupplier::apply));
- }
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/TracingUtil.java b/test/distributed/org/apache/cassandra/distributed/impl/TracingUtil.java
index d671e553d9..439d4b74b3 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/TracingUtil.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/TracingUtil.java
@@ -24,7 +24,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
-import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
/**
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/Versions.java b/test/distributed/org/apache/cassandra/distributed/impl/Versions.java
deleted file mode 100644
index 5d67f684a4..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/impl/Versions.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.impl;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.cassandra.config.Config;
-import org.apache.cassandra.utils.FBUtilities;
-
-public class Versions
-{
- private static final Logger logger = LoggerFactory.getLogger(Versions.class);
- public static Version CURRENT = new Version(FBUtilities.getReleaseVersionString(), getClassPath());
-
- private static URL[] getClassPath()
- {
- // In Java 9 the default system ClassLoader got changed from URLClassLoader to AppClassLoader which
- // does not extend URLClassLoader nor does it give access to the class path array.
- // Java requires the system property 'java.class.path' to be setup with the classpath seperated by :
- // so this logic parses that string into the URL[] needed to build later
- String cp = System.getProperty("java.class.path");
- assert cp != null && !cp.isEmpty();
- String[] split = cp.split(File.pathSeparator);
- assert split.length > 0;
- URL[] urls = new URL[split.length];
- try
- {
- for (int i = 0; i < split.length; i++)
- urls[i] = Paths.get(split[i]).toUri().toURL();
- }
- catch (MalformedURLException e)
- {
- throw new RuntimeException(e);
- }
- return urls;
- }
-
- public enum Major
- {
- v22("2\\.2\\.([0-9]+)"),
- v30("3\\.0\\.([0-9]+)"),
- v3X("3\\.([1-9]|1[01])(\\.([0-9]+))?"),
- v4("4\\.([0-9]+)");
- final Pattern pattern;
- Major(String verify)
- {
- this.pattern = Pattern.compile(verify);
- }
-
- static Major fromFull(String version)
- {
- if (version.isEmpty())
- throw new IllegalArgumentException(version);
- switch (version.charAt(0))
- {
- case '2':
- if (version.startsWith("2.2"))
- return v22;
- throw new IllegalArgumentException(version);
- case '3':
- if (version.startsWith("3.0"))
- return v30;
- return v3X;
- case '4':
- return v4;
- default:
- throw new IllegalArgumentException(version);
- }
- }
-
- // verify that the version string is valid for this major version
- boolean verify(String version)
- {
- return pattern.matcher(version).matches();
- }
-
- // sort two strings of the same major version as this enum instance
- int compare(String a, String b)
- {
- Matcher ma = pattern.matcher(a);
- Matcher mb = pattern.matcher(a);
- if (!ma.matches()) throw new IllegalArgumentException(a);
- if (!mb.matches()) throw new IllegalArgumentException(b);
- int result = Integer.compare(Integer.parseInt(ma.group(1)), Integer.parseInt(mb.group(1)));
- if (result == 0 && this == v3X && (ma.group(3) != null || mb.group(3) != null))
- {
- if (ma.group(3) != null && mb.group(3) != null)
- {
- result = Integer.compare(Integer.parseInt(ma.group(3)), Integer.parseInt(mb.group(3)));
- }
- else
- {
- result = ma.group(3) != null ? 1 : -1;
- }
- }
- // sort descending
- return -result;
- }
- }
-
- public static class Version
- {
- public final Major major;
- public final String version;
- public final URL[] classpath;
-
- public Version(String version, URL[] classpath)
- {
- this(Major.fromFull(version), version, classpath);
- }
- public Version(Major major, String version, URL[] classpath)
- {
- this.major = major;
- this.version = version;
- this.classpath = classpath;
- }
- }
-
- private final Map> versions;
- public Versions(Map> versions)
- {
- this.versions = versions;
- }
-
- public Version get(String full)
- {
- return versions.get(Major.fromFull(full))
- .stream()
- .filter(v -> full.equals(v.version))
- .findFirst()
- .orElseThrow(() -> new RuntimeException("No version " + full + " found"));
- }
-
- public Version getLatest(Major major)
- {
- return versions.get(major).stream().findFirst().orElseThrow(() -> new RuntimeException("No " + major + " versions found"));
- }
-
- public static Versions find()
- {
- final String dtestJarDirectory = System.getProperty(Config.PROPERTY_PREFIX + "test.dtest_jar_path","build");
- final File sourceDirectory = new File(dtestJarDirectory);
- logger.info("Looking for dtest jars in " + sourceDirectory.getAbsolutePath());
- final Pattern pattern = Pattern.compile("dtest-(?(\\d+)\\.(\\d+)(\\.\\d+)?(\\.\\d+)?)([~\\-]\\w[.\\w]*(?:\\-\\w[.\\w]*)*)?(\\+[.\\w]+)?\\.jar");
- final Map> versions = new HashMap<>();
- for (Major major : Major.values())
- versions.put(major, new ArrayList<>());
-
- for (File file : sourceDirectory.listFiles())
- {
- Matcher m = pattern.matcher(file.getName());
- if (!m.matches())
- continue;
- String version = m.group("fullversion");
- Major major = Major.fromFull(version);
- versions.get(major).add(new Version(major, version, new URL[] { toURL(file) }));
- }
-
- for (Map.Entry> e : versions.entrySet())
- {
- if (e.getValue().isEmpty())
- continue;
- Collections.sort(e.getValue(), Comparator.comparing(v -> v.version, e.getKey()::compare));
- logger.info("Found " + e.getValue().stream().map(v -> v.version).collect(Collectors.joining(", ")));
- }
-
- return new Versions(versions);
- }
-
- public static URL toURL(File file)
- {
- try
- {
- return file.toURI().toURL();
- }
- catch (MalformedURLException e)
- {
- throw new IllegalArgumentException(e);
- }
- }
-
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/api/IListen.java b/test/distributed/org/apache/cassandra/distributed/shared/RepairResult.java
similarity index 72%
rename from test/distributed/org/apache/cassandra/distributed/api/IListen.java
rename to test/distributed/org/apache/cassandra/distributed/shared/RepairResult.java
index c2e8dd6361..7be381a5f1 100644
--- a/test/distributed/org/apache/cassandra/distributed/api/IListen.java
+++ b/test/distributed/org/apache/cassandra/distributed/shared/RepairResult.java
@@ -16,13 +16,16 @@
* limitations under the License.
*/
-package org.apache.cassandra.distributed.api;
+package org.apache.cassandra.distributed.shared;
-public interface IListen
+public class RepairResult
{
- public interface Cancel { void cancel(); }
+ public final boolean success;
+ public final boolean wasInconsistent;
- Cancel schema(Runnable onChange);
-
- Cancel liveMembers(Runnable onChange);
+ public RepairResult(boolean success, boolean wasInconsistent)
+ {
+ this.success = success;
+ this.wasInconsistent = wasInconsistent;
+ }
}
diff --git a/test/distributed/org/apache/cassandra/distributed/test/BootstrapTest.java b/test/distributed/org/apache/cassandra/distributed/test/BootstrapTest.java
index 0af26ea0e6..11c2f9d08f 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/BootstrapTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/BootstrapTest.java
@@ -25,17 +25,21 @@ import java.util.stream.IntStream;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.cassandra.db.ConsistencyLevel;
-import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.distributed.api.IInstance;
-import org.apache.cassandra.distributed.impl.IInvokableInstance;
-import org.apache.cassandra.distributed.impl.InstanceConfig;
-import org.apache.cassandra.distributed.impl.NetworkTopology;
+import org.apache.cassandra.distributed.api.IInstanceConfig;
+import org.apache.cassandra.distributed.api.TokenSupplier;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
+import org.apache.cassandra.distributed.shared.Builder;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
import static org.apache.cassandra.distributed.api.Feature.NETWORK;
+import static org.apache.cassandra.distributed.shared.DistributedTestBase.KEYSPACE;
-public class BootstrapTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class BootstrapTest extends TestBaseImpl
{
@Test
@@ -43,24 +47,22 @@ public class BootstrapTest extends DistributedTestBase
{
int originalNodeCount = 2;
int expandedNodeCount = originalNodeCount + 1;
- Cluster.Builder builder = Cluster.build(originalNodeCount)
- .withTokenSupplier(Cluster.evenlyDistributedTokens(expandedNodeCount))
- .withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(originalNodeCount, "dc0", "rack0"))
- .withConfig(config -> config.with(NETWORK, GOSSIP));
+ Builder builder = builder().withNodes(originalNodeCount)
+ .withTokenSupplier(TokenSupplier.evenlyDistributedTokens(expandedNodeCount))
+ .withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(originalNodeCount, "dc0", "rack0"))
+ .withConfig(config -> config.with(NETWORK, GOSSIP));
Map withBootstrap = null;
Map naturally = null;
-
- try (Cluster cluster = builder.start())
+ try (ICluster cluster = builder.withNodes(originalNodeCount).start())
{
populate(cluster);
- InstanceConfig config = builder.withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(expandedNodeCount, "dc0", "rack0"))
- .newInstanceConfig(cluster);
+ IInstanceConfig config = builder.withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(expandedNodeCount, "dc0", "rack0"))
+ .newInstanceConfig(cluster);
config.set("auto_bootstrap", true);
- IInstance newInstance = cluster.bootstrap(config);
- newInstance.startup();
+ cluster.bootstrap(config).startup();
cluster.stream().forEach(instance -> {
instance.nodetool("cleanup", KEYSPACE, "tbl");
@@ -69,20 +71,21 @@ public class BootstrapTest extends DistributedTestBase
withBootstrap = count(cluster);
}
- builder = Cluster.build(expandedNodeCount)
- .withTokenSupplier(Cluster.evenlyDistributedTokens(expandedNodeCount))
+ builder = builder.withNodes(expandedNodeCount)
+ .withTokenSupplier(TokenSupplier.evenlyDistributedTokens(expandedNodeCount))
.withConfig(config -> config.with(NETWORK, GOSSIP));
- try (Cluster cluster = builder.start())
+ try (ICluster cluster = builder.start())
{
populate(cluster);
naturally = count(cluster);
}
- Assert.assertEquals(withBootstrap, naturally);
+ for (Map.Entry e : withBootstrap.entrySet())
+ Assert.assertTrue(e.getValue() >= naturally.get(e.getKey()));
}
- public void populate(Cluster cluster)
+ public void populate(ICluster cluster)
{
cluster.schemaChange("CREATE KEYSPACE " + KEYSPACE + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': " + 3 + "};");
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
@@ -93,12 +96,11 @@ public class BootstrapTest extends DistributedTestBase
i, i, i);
}
- public Map count(Cluster cluster)
+ public Map count(ICluster cluster)
{
return IntStream.rangeClosed(1, cluster.size())
.boxed()
.collect(Collectors.toMap(nodeId -> nodeId,
nodeId -> (Long) cluster.get(nodeId).executeInternal("SELECT count(*) FROM " + KEYSPACE + ".tbl")[0][0]));
}
-
-}
+}
\ No newline at end of file
diff --git a/test/distributed/org/apache/cassandra/distributed/test/CasWriteTest.java b/test/distributed/org/apache/cassandra/distributed/test/CasWriteTest.java
index 7e7c629654..a5d7e72f47 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/CasWriteTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/CasWriteTest.java
@@ -43,9 +43,10 @@ import org.junit.rules.ExpectedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.distributed.Cluster;
-import org.apache.cassandra.distributed.impl.InstanceClassLoader;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.distributed.shared.InstanceClassLoader;
import org.apache.cassandra.exceptions.CasWriteTimeoutException;
import org.apache.cassandra.exceptions.CasWriteUnknownResultException;
import org.apache.cassandra.net.Verb;
@@ -54,12 +55,13 @@ import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.fail;
+import static org.apache.cassandra.distributed.shared.AssertUtils.*;
-public class CasWriteTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class CasWriteTest extends TestBaseImpl
{
// Sharing the same cluster to boost test speed. Using a pkGen to make sure queries has distinct pk value for paxos instances.
- private static Cluster cluster;
+ private static ICluster cluster;
private static final AtomicInteger pkGen = new AtomicInteger(1_000); // preserve any pk values less than 1000 for manual queries.
private static final Logger logger = LoggerFactory.getLogger(CasWriteTest.class);
@@ -69,12 +71,12 @@ public class CasWriteTest extends DistributedTestBase
@BeforeClass
public static void setupCluster() throws Throwable
{
- cluster = init(Cluster.create(3));
+ cluster = init(Cluster.build().withNodes(3).start());
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
}
@AfterClass
- public static void close()
+ public static void close() throws Exception
{
cluster.close();
cluster = null;
@@ -106,7 +108,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtPreparePhase_ReqLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_PREPARE_REQ).from(1).to(2, 3).drop().on(); // drop the internode messages to acceptors
+ cluster.filters().verbs(Verb.PAXOS_PREPARE_REQ.id).from(1).to(2, 3).drop().on(); // drop the internode messages to acceptors
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -114,7 +116,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtPreparePhase_RspLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_PREPARE_RSP).from(2, 3).to(1).drop().on(); // drop the internode messages to acceptors
+ cluster.filters().verbs(Verb.PAXOS_PREPARE_RSP.id).from(2, 3).to(1).drop().on(); // drop the internode messages to acceptors
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -122,7 +124,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtProposePhase_ReqLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_PROPOSE_REQ).from(1).to(2, 3).drop().on();
+ cluster.filters().verbs(Verb.PAXOS_PROPOSE_REQ.id).from(1).to(2, 3).drop().on();
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -130,7 +132,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtProposePhase_RspLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_PROPOSE_RSP).from(2, 3).to(1).drop().on();
+ cluster.filters().verbs(Verb.PAXOS_PROPOSE_RSP.id).from(2, 3).to(1).drop().on();
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -138,7 +140,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtCommitPhase_ReqLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_COMMIT_REQ).from(1).to(2, 3).drop().on();
+ cluster.filters().verbs(Verb.PAXOS_COMMIT_REQ.id).from(1).to(2, 3).drop().on();
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -146,7 +148,7 @@ public class CasWriteTest extends DistributedTestBase
public void testCasWriteTimeoutAtCommitPhase_RspLost()
{
expectCasWriteTimeout();
- cluster.verbs(Verb.PAXOS_COMMIT_RSP).from(2, 3).to(1).drop().on();
+ cluster.filters().verbs(Verb.PAXOS_COMMIT_RSP.id).from(2, 3).to(1).drop().on();
cluster.coordinator(1).execute(mkUniqueCasInsertQuery(1), ConsistencyLevel.QUORUM);
}
@@ -159,8 +161,8 @@ public class CasWriteTest extends DistributedTestBase
Arrays.asList(1, 3),
c -> {
c.filters().reset();
- c.verbs(Verb.PAXOS_PREPARE_REQ).from(1).to(3).drop();
- c.verbs(Verb.PAXOS_PROPOSE_REQ).from(1).to(2).drop();
+ c.filters().verbs(Verb.PAXOS_PREPARE_REQ.id).from(1).to(3).drop();
+ c.filters().verbs(Verb.PAXOS_PROPOSE_REQ.id).from(1).to(2).drop();
},
failure ->
failure.get() != null &&
@@ -172,7 +174,7 @@ public class CasWriteTest extends DistributedTestBase
private void testWithContention(int testUid,
List contendingNodes,
- Consumer setupForEachRound,
+ Consumer setupForEachRound,
Function, Boolean> expectedException,
String assertHintMessage) throws InterruptedException
{
diff --git a/test/distributed/org/apache/cassandra/distributed/test/DistributedRepairUtils.java b/test/distributed/org/apache/cassandra/distributed/test/DistributedRepairUtils.java
index 7f162e1465..023d02ce1c 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/DistributedRepairUtils.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/DistributedRepairUtils.java
@@ -26,12 +26,12 @@ import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
-import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.api.NodeToolResult;
import org.apache.cassandra.distributed.api.QueryResult;
import org.apache.cassandra.distributed.api.Row;
import org.apache.cassandra.distributed.impl.AbstractCluster;
-import org.apache.cassandra.distributed.impl.IInvokableInstance;
import org.apache.cassandra.metrics.StorageMetrics;
import static org.apache.cassandra.utils.Retry.retryWithBackoffBlocking;
diff --git a/test/distributed/org/apache/cassandra/distributed/test/DistributedTestBase.java b/test/distributed/org/apache/cassandra/distributed/test/DistributedTestBase.java
deleted file mode 100644
index f89f8f491c..0000000000
--- a/test/distributed/org/apache/cassandra/distributed/test/DistributedTestBase.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.distributed.test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import com.google.common.collect.Iterators;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-
-import com.datastax.driver.core.ResultSet;
-import org.apache.cassandra.config.DatabaseDescriptor;
-import org.apache.cassandra.distributed.impl.AbstractCluster;
-import org.apache.cassandra.distributed.impl.IsolatedExecutor;
-import org.apache.cassandra.distributed.impl.RowUtil;
-
-public class DistributedTestBase
-{
- @After
- public void afterEach()
- {
- System.runFinalization();
- System.gc();
- }
-
- public static String KEYSPACE = "distributed_test_keyspace";
-
- public static void nativeLibraryWorkaround()
- {
- // Disable the Netty tcnative library otherwise the io.netty.internal.tcnative.CertificateCallbackTask,
- // CertificateVerifierTask, SSLPrivateKeyMethodDecryptTask, SSLPrivateKeyMethodSignTask,
- // SSLPrivateKeyMethodTask, and SSLTask hold a gcroot against the InstanceClassLoader.
- System.setProperty("cassandra.disable_tcactive_openssl", "true");
- System.setProperty("io.netty.transport.noNative", "true");
- }
-
- public static void processReaperWorkaround()
- {
- // Make sure the 'process reaper' thread is initially created under the main classloader,
- // otherwise it gets created with the contextClassLoader pointing to an InstanceClassLoader
- // which prevents it from being garbage collected.
- IsolatedExecutor.ThrowingRunnable.toRunnable(() -> new ProcessBuilder().command("true").start().waitFor()).run();
- }
-
- @BeforeClass
- public static void setup()
- {
- System.setProperty("cassandra.ring_delay_ms", Integer.toString(10 * 1000));
- System.setProperty("org.apache.cassandra.disable_mbean_registration", "true");
- nativeLibraryWorkaround();
- processReaperWorkaround();
- DatabaseDescriptor.clientInitialization();
- }
-
- static String withKeyspace(String replaceIn)
- {
- return String.format(replaceIn, KEYSPACE);
- }
-
- protected static > C init(C cluster)
- {
- return init(cluster, cluster.size());
- }
-
- protected static > C init(C cluster, int replicationFactor)
- {
- cluster.schemaChange("CREATE KEYSPACE " + KEYSPACE + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': " + replicationFactor + "};");
- return cluster;
- }
-
- public static void assertRows(ResultSet actual,Object[]... expected)
- {
- assertRows(RowUtil.toObjects(actual), expected);
- }
-
- public static void assertRows(Object[][] actual, Object[]... expected)
- {
- Assert.assertEquals(rowsNotEqualErrorMessage(actual, expected),
- expected.length, actual.length);
-
- for (int i = 0; i < expected.length; i++)
- {
- Object[] expectedRow = expected[i];
- Object[] actualRow = actual[i];
- Assert.assertTrue(rowsNotEqualErrorMessage(actual, expected),
- Arrays.equals(expectedRow, actualRow));
- }
- }
-
- public static void assertRow(Object[] actual, Object... expected)
- {
- Assert.assertTrue(rowNotEqualErrorMessage(actual, expected),
- Arrays.equals(actual, expected));
- }
-
- public static void assertRows(Iterator actual, Iterator expected)
- {
- while (actual.hasNext() && expected.hasNext())
- assertRow(actual.next(), expected.next());
-
- Assert.assertEquals("Resultsets have different sizes", actual.hasNext(), expected.hasNext());
- }
-
- public static void assertRows(Iterator actual, Object[]... expected)
- {
- assertRows(actual, Iterators.forArray(expected));
- }
-
- public static String rowNotEqualErrorMessage(Object[] actual, Object[] expected)
- {
- return String.format("Expected: %s\nActual:%s\n",
- Arrays.toString(expected),
- Arrays.toString(actual));
- }
-
- public static String rowsNotEqualErrorMessage(Object[][] actual, Object[][] expected)
- {
- return String.format("Expected: %s\nActual: %s\n",
- rowsToString(expected),
- rowsToString(actual));
- }
-
- public static String rowsToString(Object[][] rows)
- {
- StringBuilder builder = new StringBuilder();
- builder.append("[");
- boolean isFirst = true;
- for (Object[] row : rows)
- {
- if (isFirst)
- isFirst = false;
- else
- builder.append(",");
- builder.append(Arrays.toString(row));
- }
- builder.append("]");
- return builder.toString();
- }
-
- public static Object[][] toObjectArray(Iterator iter)
- {
- List res = new ArrayList<>();
- while (iter.hasNext())
- res.add(iter.next());
-
- return res.toArray(new Object[res.size()][]);
- }
-
- public static Object[] row(Object... expected)
- {
- return expected;
- }
-}
diff --git a/test/distributed/org/apache/cassandra/distributed/impl/ExecUtil.java b/test/distributed/org/apache/cassandra/distributed/test/ExecUtil.java
similarity index 96%
rename from test/distributed/org/apache/cassandra/distributed/impl/ExecUtil.java
rename to test/distributed/org/apache/cassandra/distributed/test/ExecUtil.java
index b907626ae8..b9fbd5cbb0 100644
--- a/test/distributed/org/apache/cassandra/distributed/impl/ExecUtil.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/ExecUtil.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.cassandra.distributed.impl;
+package org.apache.cassandra.distributed.test;
import java.io.Serializable;
diff --git a/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java b/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java
index 25e299c0d6..bad6d87c8f 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java
@@ -45,7 +45,8 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.apache.cassandra.db.ColumnFamilyStore;
-import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.apache.cassandra.db.DataRange;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.PartitionPosition;
@@ -54,10 +55,10 @@ import org.apache.cassandra.db.rows.UnfilteredRowIterator;
import org.apache.cassandra.dht.AbstractBounds;
import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
-import org.apache.cassandra.distributed.Cluster;
import org.apache.cassandra.distributed.api.Feature;
+import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.distributed.api.IIsolatedExecutor.SerializableRunnable;
-import org.apache.cassandra.distributed.impl.IInvokableInstance;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.impl.InstanceKiller;
import org.apache.cassandra.io.sstable.CorruptSSTableException;
import org.apache.cassandra.io.sstable.ISSTableScanner;
@@ -73,9 +74,9 @@ import org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus;
import org.apache.cassandra.service.StorageService;
@RunWith(Parameterized.class)
-public class FailingRepairTest extends DistributedTestBase implements Serializable
+public class FailingRepairTest extends TestBaseImpl implements Serializable
{
- private static Cluster CLUSTER;
+ private static ICluster CLUSTER;
private final Verb messageType;
private final RepairParallelism parallelism;
@@ -136,15 +137,16 @@ public class FailingRepairTest extends DistributedTestBase implements Serializab
{
// streaming requires networking ATM
// streaming also requires gossip or isn't setup properly
- CLUSTER = init(Cluster.build(2)
- .withConfig(c -> c.with(Feature.NETWORK)
- .with(Feature.GOSSIP)
- .set("disk_failure_policy", "die"))
- .start());
+ CLUSTER = init(Cluster.build()
+ .withNodes(2)
+ .withConfig(c -> c.with(Feature.NETWORK)
+ .with(Feature.GOSSIP)
+ .set("disk_failure_policy", "die"))
+ .start());
}
@AfterClass
- public static void teardownCluster()
+ public static void teardownCluster() throws Exception
{
if (CLUSTER != null)
CLUSTER.close();
@@ -154,7 +156,7 @@ public class FailingRepairTest extends DistributedTestBase implements Serializab
public void cleanupState()
{
for (int i = 1; i <= CLUSTER.size(); i++)
- CLUSTER.get(i).runOnInstance(() -> InstanceKiller.clear());
+ CLUSTER.get(i).runOnInstance(InstanceKiller::clear);
}
@Test(timeout = 10 * 60 * 1000)
diff --git a/test/distributed/org/apache/cassandra/distributed/test/GossipSettlesTest.java b/test/distributed/org/apache/cassandra/distributed/test/GossipSettlesTest.java
index 5f1263af1d..509fe6f006 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/GossipSettlesTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/GossipSettlesTest.java
@@ -18,23 +18,25 @@
package org.apache.cassandra.distributed.test;
-import java.io.IOException;
-
import org.junit.Test;
-import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ICluster;
import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
import static org.apache.cassandra.distributed.api.Feature.NETWORK;
-public class GossipSettlesTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class GossipSettlesTest extends TestBaseImpl
{
@Test
- public void testGossipSettles() throws IOException
+ public void testGossipSettles() throws Throwable
{
- // Use withSubnet(1) to prove seed provider is set correctly - without the fix to pass a seed provider, this test fails
- try (Cluster cluster = Cluster.build(3).withConfig(config -> config.with(GOSSIP).with(NETWORK)).withSubnet(1).start())
+ /* Use withSubnet(1) to prove seed provider is set correctly - without the fix to pass a seed provider, this test fails */
+ try (ICluster cluster = builder().withNodes(3)
+ .withConfig(config -> config.with(GOSSIP).with(NETWORK))
+ .withSubnet(1)
+ .start())
{
}
}
diff --git a/test/distributed/org/apache/cassandra/distributed/test/LargeColumnTest.java b/test/distributed/org/apache/cassandra/distributed/test/LargeColumnTest.java
index 0c28d38ffd..0a81359dcf 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/LargeColumnTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/LargeColumnTest.java
@@ -20,21 +20,22 @@ package org.apache.cassandra.distributed.test;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.cassandra.db.ConsistencyLevel;
-import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ICluster;
import static java.util.concurrent.TimeUnit.SECONDS;
-public class LargeColumnTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class LargeColumnTest extends TestBaseImpl
{
private static final Logger logger = LoggerFactory.getLogger(LargeColumnTest.class);
+
private static String str(int length, Random random, long seed)
{
random.setSeed(seed);
@@ -63,23 +64,24 @@ public class LargeColumnTest extends DistributedTestBase
long seed = ThreadLocalRandom.current().nextLong();
logger.info("Using seed {}", seed);
- try (Cluster cluster = init(Cluster.build(nodes)
- .withConfig(config ->
- config.set("commitlog_segment_size_in_mb", (columnSize * 3) >> 20)
- .set("internode_application_send_queue_reserve_endpoint_capacity_in_bytes", columnSize * 2)
- .set("internode_application_send_queue_reserve_global_capacity_in_bytes", columnSize * 3)
- .set("write_request_timeout_in_ms", SECONDS.toMillis(30L))
- .set("read_request_timeout_in_ms", SECONDS.toMillis(30L))
- .set("memtable_heap_space_in_mb", 1024)
- )
- .start()))
+ try (ICluster cluster = init(builder()
+ .withNodes(nodes)
+ .withConfig(config ->
+ config.set("commitlog_segment_size_in_mb", (columnSize * 3) >> 20)
+ .set("internode_application_send_queue_reserve_endpoint_capacity_in_bytes", columnSize * 2)
+ .set("internode_application_send_queue_reserve_global_capacity_in_bytes", columnSize * 3)
+ .set("write_request_timeout_in_ms", SECONDS.toMillis(30L))
+ .set("read_request_timeout_in_ms", SECONDS.toMillis(30L))
+ .set("memtable_heap_space_in_mb", 1024)
+ )
+ .start()))
{
cluster.schemaChange(String.format("CREATE TABLE %s.cf (k int, c text, PRIMARY KEY (k))", KEYSPACE));
- for (int i = 0 ; i < rowCount ; ++i)
+ for (int i = 0; i < rowCount; ++i)
cluster.coordinator(1).execute(String.format("INSERT INTO %s.cf (k, c) VALUES (?, ?);", KEYSPACE), ConsistencyLevel.ALL, i, str(columnSize, random, seed | i));
- for (int i = 0 ; i < rowCount ; ++i)
+ for (int i = 0; i < rowCount; ++i)
{
Object[][] results = cluster.coordinator(1).execute(String.format("SELECT k, c FROM %s.cf WHERE k = ?;", KEYSPACE), ConsistencyLevel.ALL, i);
Assert.assertTrue(str(columnSize, random, seed | i).equals(results[0][1]));
@@ -92,5 +94,4 @@ public class LargeColumnTest extends DistributedTestBase
{
testLargeColumns(2, 16 << 20, 5);
}
-
-}
+}
\ No newline at end of file
diff --git a/test/distributed/org/apache/cassandra/distributed/test/MessageFiltersTest.java b/test/distributed/org/apache/cassandra/distributed/test/MessageFiltersTest.java
index 814e2296d0..bd09891aa0 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/MessageFiltersTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/MessageFiltersTest.java
@@ -18,6 +18,7 @@
package org.apache.cassandra.distributed.test;
+import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -29,20 +30,22 @@ import com.google.common.collect.Sets;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
import org.apache.cassandra.distributed.api.IIsolatedExecutor;
import org.apache.cassandra.distributed.api.IMessage;
import org.apache.cassandra.distributed.api.IMessageFilters;
import org.apache.cassandra.distributed.impl.Instance;
-import org.apache.cassandra.distributed.impl.MessageFilters;
+import org.apache.cassandra.distributed.shared.MessageFilters;
import org.apache.cassandra.locator.InetAddressAndPort;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.net.NoPayload;
import org.apache.cassandra.net.Verb;
-public class MessageFiltersTest extends DistributedTestBase
+public class MessageFiltersTest extends TestBaseImpl
{
@Test
public void simpleInboundFiltersTest()
@@ -73,7 +76,7 @@ public class MessageFiltersTest extends DistributedTestBase
String MSG2 = "msg2";
MessageFilters filters = new MessageFilters();
- Permit permit = inbound ? (from, to, msg) -> filters.permitInbound(from, to, msg) : (from, to, msg) -> filters.permitOutbound(from, to, msg);
+ Permit permit = inbound ? filters::permitInbound : filters::permitOutbound;
IMessageFilters.Filter filter = filters.allVerbs().inbound(inbound).from(1).drop();
Assert.assertFalse(permit.test(i1, i2, msg(VERB1, MSG1)));
@@ -136,7 +139,11 @@ public class MessageFiltersTest extends DistributedTestBase
public byte[] bytes() { return msg.getBytes(); }
public int id() { return 0; }
public int version() { return 0; }
- public InetAddressAndPort from() { return null; }
+ public InetSocketAddress from() { return null; }
+ public int fromPort()
+ {
+ return 0;
+ }
};
}
@@ -146,7 +153,7 @@ public class MessageFiltersTest extends DistributedTestBase
String read = "SELECT * FROM " + KEYSPACE + ".tbl";
String write = "INSERT INTO " + KEYSPACE + ".tbl (pk, ck, v) VALUES (1, 1, 1)";
- try (Cluster cluster = Cluster.create(2))
+ try (ICluster cluster = builder().withNodes(2).start())
{
cluster.schemaChange("CREATE KEYSPACE " + KEYSPACE + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': " + cluster.size() + "};");
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
@@ -176,7 +183,7 @@ public class MessageFiltersTest extends DistributedTestBase
String read = "SELECT * FROM " + KEYSPACE + ".tbl";
String write = "INSERT INTO " + KEYSPACE + ".tbl (pk, ck, v) VALUES (1, 1, 1)";
- try (Cluster cluster = Cluster.create(2))
+ try (ICluster cluster = builder().withNodes(2).start())
{
cluster.schemaChange("CREATE KEYSPACE " + KEYSPACE + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': " + cluster.size() + "};");
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck))");
@@ -224,7 +231,8 @@ public class MessageFiltersTest extends DistributedTestBase
{
try (Cluster cluster = Cluster.create(2))
{
- InetAddressAndPort other = cluster.get(2).broadcastAddressAndPort();
+ InetAddressAndPort other = InetAddressAndPort.getByAddressOverrideDefaults(cluster.get(2).broadcastAddress().getAddress(),
+ cluster.get(2).broadcastAddress().getPort());
CountDownLatch waitForIt = new CountDownLatch(1);
Set outboundMessagesSeen = new HashSet<>();
Set inboundMessagesSeen = new HashSet<>();
diff --git a/test/distributed/org/apache/cassandra/distributed/test/MessageForwardingTest.java b/test/distributed/org/apache/cassandra/distributed/test/MessageForwardingTest.java
index 17bd6e1d92..153d7de706 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/MessageForwardingTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/MessageForwardingTest.java
@@ -32,44 +32,44 @@ import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.apache.cassandra.distributed.Cluster;
import org.apache.cassandra.distributed.impl.IsolatedExecutor;
import org.apache.cassandra.distributed.impl.TracingUtil;
import org.apache.cassandra.utils.UUIDGen;
-public class MessageForwardingTest extends DistributedTestBase
+public class MessageForwardingTest extends TestBaseImpl
{
@Test
public void mutationsForwardedToAllReplicasTest()
{
String originalTraceTimeout = TracingUtil.setWaitForTracingEventTimeoutSecs("1");
final int numInserts = 100;
- Map forwardFromCounts = new HashMap<>();
- Map commitCounts = new HashMap<>();
+ Map forwardFromCounts = new HashMap<>();
+ Map commitCounts = new HashMap<>();
- try (Cluster cluster = init(Cluster.build()
- .withDC("dc0", 1)
- .withDC("dc1", 3)
- .start()))
+ try (Cluster cluster = (Cluster) init(builder()
+ .withDC("dc0", 1)
+ .withDC("dc1", 3)
+ .start()))
{
cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v text, PRIMARY KEY (pk, ck))");
- cluster.forEach(instance -> commitCounts.put(instance.broadcastAddressAndPort().address, 0));
+ cluster.forEach(instance -> commitCounts.put(instance.broadcastAddress().getAddress(), 0));
final UUID sessionId = UUIDGen.getTimeUUID();
- Stream> inserts = IntStream.range(0, numInserts).mapToObj((idx) ->
- cluster.coordinator(1).asyncExecuteWithTracing(sessionId,
- "INSERT INTO " + KEYSPACE + ".tbl(pk,ck,v) VALUES (1, 1, 'x')",
- ConsistencyLevel.ALL)
- );
+ Stream> inserts = IntStream.range(0, numInserts).mapToObj((idx) -> {
+ return cluster.coordinator(1).asyncExecuteWithTracing(sessionId,
+ "INSERT INTO " + KEYSPACE + ".tbl(pk,ck,v) VALUES (1, 1, 'x')",
+ ConsistencyLevel.ALL);
+ });
// Wait for each of the futures to complete before checking the traces, don't care
// about the result so
//noinspection ResultOfMethodCallIgnored
inserts.map(IsolatedExecutor::waitOn).collect(Collectors.toList());
- cluster.stream("dc1").forEach(instance -> forwardFromCounts.put(instance.broadcastAddressAndPort().address, 0));
- cluster.forEach(instance -> commitCounts.put(instance.broadcastAddressAndPort().address, 0));
+ cluster.stream("dc1").forEach(instance -> forwardFromCounts.put(instance.broadcastAddress().getAddress(), 0));
+ cluster.forEach(instance -> commitCounts.put(instance.broadcastAddress().getAddress(), 0));
List traces = TracingUtil.getTrace(cluster, sessionId, ConsistencyLevel.ALL);
traces.forEach(traceEntry -> {
if (traceEntry.activity.contains("Appending to commitlog"))
@@ -100,4 +100,4 @@ public class MessageForwardingTest extends DistributedTestBase
TracingUtil.setWaitForTracingEventTimeoutSecs(originalTraceTimeout);
}
}
-}
+}
\ No newline at end of file
diff --git a/test/distributed/org/apache/cassandra/distributed/test/NativeProtocolTest.java b/test/distributed/org/apache/cassandra/distributed/test/NativeProtocolTest.java
index 45d9840f81..0905b92f53 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/NativeProtocolTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/NativeProtocolTest.java
@@ -18,50 +18,53 @@
package org.apache.cassandra.distributed.test;
+import org.apache.cassandra.distributed.impl.RowUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.Statement;
-import org.apache.cassandra.distributed.Cluster;
-import org.apache.cassandra.distributed.impl.RowUtil;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Iterator;
+import org.apache.cassandra.distributed.api.ICluster;
import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
import static org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL;
import static org.apache.cassandra.distributed.api.Feature.NETWORK;
+import static org.apache.cassandra.distributed.shared.AssertUtils.*;
-public class NativeProtocolTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class NativeProtocolTest extends TestBaseImpl
{
@Test
public void withClientRequests() throws Throwable
{
- try (Cluster ignored = init(Cluster.create(3,
- config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))))
+ try (ICluster ignored = init(builder().withNodes(3)
+ .withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))
+ .start()))
{
- final com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
- Session session = cluster.connect();
- session.execute("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));");
- session.execute("INSERT INTO " + KEYSPACE + ".tbl (pk, ck, v) values (1,1,1);");
- Statement select = new SimpleStatement("select * from " + KEYSPACE + ".tbl;").setConsistencyLevel(ConsistencyLevel.ALL);
- final ResultSet resultSet = session.execute(select);
- assertRows(resultSet, row(1, 1, 1));
- Assert.assertEquals(3, cluster.getMetadata().getAllHosts().size());
- session.close();
- cluster.close();
+
+ try (com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
+ Session session = cluster.connect())
+ {
+ session.execute("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));");
+ session.execute("INSERT INTO " + KEYSPACE + ".tbl (pk, ck, v) values (1,1,1);");
+ Statement select = new SimpleStatement("select * from " + KEYSPACE + ".tbl;").setConsistencyLevel(ConsistencyLevel.ALL);
+ final ResultSet resultSet = session.execute(select);
+ assertRows(RowUtil.toObjects(resultSet), row(1, 1, 1));
+ Assert.assertEquals(3, cluster.getMetadata().getAllHosts().size());
+ }
}
}
@Test
public void withCounters() throws Throwable
{
- try (Cluster dtCluster = init(Cluster.create(3,
- config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))))
+ try (ICluster ignored = init(builder().withNodes(3)
+ .withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL))
+ .start()))
{
final com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
Session session = cluster.connect();
@@ -69,7 +72,7 @@ public class NativeProtocolTest extends DistributedTestBase
session.execute("UPDATE " + KEYSPACE + ".tbl set ck = ck + 10 where pk = 1;");
Statement select = new SimpleStatement("select * from " + KEYSPACE + ".tbl;").setConsistencyLevel(ConsistencyLevel.ALL);
final ResultSet resultSet = session.execute(select);
- assertRows(resultSet, row(1, 10L));
+ assertRows(RowUtil.toObjects(resultSet), row(1, 10L));
Assert.assertEquals(3, cluster.getMetadata().getAllHosts().size());
session.close();
cluster.close();
diff --git a/test/distributed/org/apache/cassandra/distributed/test/NetworkTopologyTest.java b/test/distributed/org/apache/cassandra/distributed/test/NetworkTopologyTest.java
index a9c2cee0d6..8230fd5e54 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/NetworkTopologyTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/NetworkTopologyTest.java
@@ -26,22 +26,23 @@ import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ICluster;
import org.apache.cassandra.distributed.api.IInstance;
-import org.apache.cassandra.distributed.impl.NetworkTopology;
-import org.apache.cassandra.utils.Pair;
+import org.apache.cassandra.distributed.api.IInvokableInstance;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
-public class NetworkTopologyTest extends DistributedTestBase
+// TODO: this test should be removed after running in-jvm dtests is set up via the shared API repository
+public class NetworkTopologyTest extends TestBaseImpl
{
@Test
public void namedDcTest() throws Throwable
{
- try (Cluster cluster = Cluster.build()
- .withNodeIdTopology(Collections.singletonMap(1, NetworkTopology.dcAndRack("somewhere", "rack0")))
- .withRack("elsewhere", "firstrack", 1)
- .withRack("elsewhere", "secondrack", 2)
- .withDC("nearthere", 4)
- .start())
+ try (ICluster cluster = builder()
+ .withNodeIdTopology(Collections.singletonMap(1, NetworkTopology.dcAndRack("somewhere", "rack0")))
+ .withRack("elsewhere", "firstrack", 1)
+ .withRack("elsewhere", "secondrack", 2)
+ .withDC("nearthere", 4)
+ .start())
{
Assert.assertEquals(1, cluster.stream("somewhere").count());
Assert.assertEquals(1, cluster.stream("elsewhere", "firstrack").count());
@@ -61,9 +62,8 @@ public class NetworkTopologyTest extends DistributedTestBase
public void automaticNamedDcTest() throws Throwable
{
- try (Cluster cluster = Cluster.build()
- .withRacks(2, 1, 3)
- .start())
+ try (ICluster cluster = builder().withRacks(2, 1, 3)
+ .start())
{
Assert.assertEquals(6, cluster.stream().count());
Assert.assertEquals(3, cluster.stream("datacenter1").count());
@@ -74,27 +74,25 @@ public class NetworkTopologyTest extends DistributedTestBase
@Test(expected = IllegalStateException.class)
public void noCountsAfterNamingDCsTest()
{
- Cluster.build()
- .withDC("nameddc", 1)
- .withDCs(1);
+ builder().withDC("nameddc", 1)
+ .withDCs(1);
}
@Test(expected = IllegalStateException.class)
public void mustProvideNodeCountBeforeWithDCsTest()
{
- Cluster.build()
- .withDCs(1);
+ builder().withDCs(1);
}
@Test(expected = IllegalStateException.class)
public void noEmptyNodeIdTopologyTest()
{
- Cluster.build().withNodeIdTopology(Collections.emptyMap());
+ builder().withNodeIdTopology(Collections.emptyMap());
}
@Test(expected = IllegalStateException.class)
public void noHolesInNodeIdTopologyTest()
{
- Cluster.build().withNodeIdTopology(Collections.singletonMap(2, NetworkTopology.dcAndRack("doomed", "rack")));
+ builder().withNodeIdTopology(Collections.singletonMap(2, NetworkTopology.dcAndRack("doomed", "rack")));
}
-}
+}
\ No newline at end of file
diff --git a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
index e209d1d413..1a1bdc797a 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
@@ -20,16 +20,16 @@ package org.apache.cassandra.distributed.test;
import org.junit.Test;
-import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ICluster;
import static org.junit.Assert.assertEquals;
-public class NodeToolTest extends DistributedTestBase
+public class NodeToolTest extends TestBaseImpl
{
@Test
public void test() throws Throwable
{
- try (Cluster cluster = init(Cluster.create(1)))
+ try (ICluster cluster = init(builder().withNodes(1).start()))
{
assertEquals(0, cluster.get(1).nodetool("help"));
assertEquals(0, cluster.get(1).nodetool("flush"));
diff --git a/test/distributed/org/apache/cassandra/distributed/test/PreviewRepairTest.java b/test/distributed/org/apache/cassandra/distributed/test/PreviewRepairTest.java
index c712948bf2..30c8f25a24 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/PreviewRepairTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/PreviewRepairTest.java
@@ -34,23 +34,23 @@ import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.apache.cassandra.db.ColumnFamilyStore;
-import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.compaction.CompactionManager;
import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.apache.cassandra.distributed.api.ICoordinator;
import org.apache.cassandra.distributed.api.IIsolatedExecutor;
import org.apache.cassandra.distributed.api.IMessage;
import org.apache.cassandra.distributed.api.IMessageFilters;
+import org.apache.cassandra.distributed.shared.RepairResult;
import org.apache.cassandra.net.Verb;
import org.apache.cassandra.repair.RepairParallelism;
import org.apache.cassandra.repair.messages.RepairOption;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.streaming.PreviewKind;
import org.apache.cassandra.utils.FBUtilities;
-import org.apache.cassandra.utils.Pair;
import org.apache.cassandra.utils.concurrent.SimpleCondition;
import org.apache.cassandra.utils.progress.ProgressEventType;
@@ -60,7 +60,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-public class PreviewRepairTest extends DistributedTestBase
+public class PreviewRepairTest extends TestBaseImpl
{
/**
* makes sure that the repaired sstables are not matching on the two
@@ -93,9 +93,9 @@ public class PreviewRepairTest extends DistributedTestBase
cfs.enableAutoCompaction();
FBUtilities.waitOnFutures(CompactionManager.instance.submitBackground(cfs));
});
- Pair rs = cluster.get(1).callOnInstance(repair(options(true)));
- assertTrue(rs.left); // preview repair should succeed
- assertFalse(rs.right); // and we should see no mismatches
+ RepairResult rs = cluster.get(1).callOnInstance(repair(options(true)));
+ assertTrue(rs.success); // preview repair should succeed
+ assertFalse(rs.wasInconsistent); // and we should see no mismatches
}
}
@@ -133,14 +133,14 @@ public class PreviewRepairTest extends DistributedTestBase
// this pauses the validation request sent from node1 to node2 until we have run a full inc repair below
cluster.filters().outbound().verbs(Verb.VALIDATION_REQ.id).from(1).to(2).messagesMatching(filter).drop();
- Future> rsFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true))));
+ Future rsFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true))));
Thread.sleep(1000);
// this needs to finish before the preview repair is unpaused on node2
cluster.get(1).callOnInstance(repair(options(false)));
continuePreviewRepair.signalAll();
- Pair rs = rsFuture.get();
- assertFalse(rs.left); // preview repair should have failed
- assertFalse(rs.right); // and no mismatches should have been reported
+ RepairResult rs = rsFuture.get();
+ assertFalse(rs.success); // preview repair should have failed
+ assertFalse(rs.wasInconsistent); // and no mismatches should have been reported
}
finally
{
@@ -162,7 +162,7 @@ public class PreviewRepairTest extends DistributedTestBase
insert(cluster.coordinator(1), 0, 100);
cluster.forEach((node) -> node.flush(KEYSPACE));
- assertTrue(cluster.get(1).callOnInstance(repair(options(false))).left);
+ assertTrue(cluster.get(1).callOnInstance(repair(options(false))).success);
insert(cluster.coordinator(1), 100, 100);
cluster.forEach((node) -> node.flush(KEYSPACE));
@@ -181,15 +181,15 @@ public class PreviewRepairTest extends DistributedTestBase
});
assertEquals(2, localRanges.size());
- Future> repairStatusFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true, localRanges.get(0)))));
+ Future repairStatusFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true, localRanges.get(0)))));
Thread.sleep(1000); // wait for node1 to start validation compaction
// this needs to finish before the preview repair is unpaused on node2
- assertTrue(cluster.get(1).callOnInstance(repair(options(false, localRanges.get(1)))).left);
+ assertTrue(cluster.get(1).callOnInstance(repair(options(false, localRanges.get(1)))).success);
continuePreviewRepair.signalAll();
- Pair rs = repairStatusFuture.get();
- assertTrue(rs.left); // repair should succeed
- assertFalse(rs.right); // and no mismatches
+ RepairResult rs = repairStatusFuture.get();
+ assertTrue(rs.success); // repair should succeed
+ assertFalse(rs.wasInconsistent); // and no mismatches
}
finally
{
@@ -231,7 +231,7 @@ public class PreviewRepairTest extends DistributedTestBase
/**
* returns a pair with [repair success, was inconsistent]
*/
- private static IIsolatedExecutor.SerializableCallable> repair(Map