diff --git a/src/org/apache/cassandra/dht/StringToken.java b/src/org/apache/cassandra/dht/StringToken.java index a1939ddac7..5b6ebe71fd 100644 --- a/src/org/apache/cassandra/dht/StringToken.java +++ b/src/org/apache/cassandra/dht/StringToken.java @@ -2,7 +2,7 @@ package org.apache.cassandra.dht; public class StringToken extends Token { - protected StringToken(String token) + public StringToken(String token) { super(token); } diff --git a/src/org/apache/cassandra/service/StorageService.java b/src/org/apache/cassandra/service/StorageService.java index c6e6fdc89e..5635d6d59f 100644 --- a/src/org/apache/cassandra/service/StorageService.java +++ b/src/org/apache/cassandra/service/StorageService.java @@ -867,6 +867,9 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto public String getToken(EndPoint ep) { + // render a String representation of the Token corresponding to this endpoint + // for a human-facing UI. If there is no such Token then we use "" since + // it is not a valid value either for BigIntegerToken or StringToken. EndPoint ep2 = new EndPoint(ep.getHost(), DatabaseDescriptor.getStoragePort()); Token token = tokenMetadata_.getToken(ep2); // if there is no token for an endpoint, return an empty string to denote that diff --git a/test/org/apache/cassandra/locator/RackUnawareStrategyTest.java b/test/org/apache/cassandra/locator/RackUnawareStrategyTest.java new file mode 100644 index 0000000000..fcf508caad --- /dev/null +++ b/test/org/apache/cassandra/locator/RackUnawareStrategyTest.java @@ -0,0 +1,72 @@ +package org.apache.cassandra.locator; + +import java.util.List; +import java.util.ArrayList; +import java.math.BigInteger; + +import org.testng.annotations.Test; +import org.apache.cassandra.dht.IPartitioner; +import org.apache.cassandra.dht.RandomPartitioner; +import org.apache.cassandra.dht.BigIntegerToken; +import org.apache.cassandra.dht.Token; +import org.apache.cassandra.dht.OrderPreservingPartitioner; +import org.apache.cassandra.dht.StringToken; +import org.apache.cassandra.net.EndPoint; + +public class RackUnawareStrategyTest +{ + @Test + public void testBigIntegerStorageEndPoints() + { + TokenMetadata tmd = new TokenMetadata(); + IPartitioner partitioner = new RandomPartitioner(); + IReplicaPlacementStrategy strategy = new RackUnawareStrategy(tmd, partitioner, 3, 7000); + + List endPointTokens = new ArrayList(); + List keyTokens = new ArrayList(); + for (int i = 0; i < 5; i++) { + endPointTokens.add(new BigIntegerToken(String.valueOf(10 * i))); + keyTokens.add(new BigIntegerToken(String.valueOf(10 * i + 5))); + } + testGetStorageEndPoints(tmd, strategy, endPointTokens.toArray(new Token[0]), keyTokens.toArray(new Token[0])); + } + + @Test + public void testStringStorageEndPoints() + { + TokenMetadata tmd = new TokenMetadata(); + IPartitioner partitioner = new OrderPreservingPartitioner(); + IReplicaPlacementStrategy strategy = new RackUnawareStrategy(tmd, partitioner, 3, 7000); + + List endPointTokens = new ArrayList(); + List keyTokens = new ArrayList(); + for (int i = 0; i < 5; i++) { + endPointTokens.add(new StringToken(String.valueOf((char)('a' + i * 2)))); + keyTokens.add(partitioner.getTokenForKey(String.valueOf((char)('a' + i * 2 + 1)))); + } + testGetStorageEndPoints(tmd, strategy, endPointTokens.toArray(new Token[0]), keyTokens.toArray(new Token[0])); + } + + // given a list of endpoint tokens, and a set of key tokens falling between the endpoint tokens, + // make sure that the Strategy picks the right endpoints for the keys. + private void testGetStorageEndPoints(TokenMetadata tmd, IReplicaPlacementStrategy strategy, Token[] endPointTokens, Token[] keyTokens) + { + List hosts = new ArrayList(); + for (int i = 0; i < endPointTokens.length; i++) + { + EndPoint ep = new EndPoint(String.valueOf(i), 7001); + tmd.update(endPointTokens[i], ep); + hosts.add(ep); + } + + for (int i = 0; i < keyTokens.length; i++) + { + EndPoint[] endPoints = strategy.getStorageEndPoints(keyTokens[i]); + assert endPoints.length == 3; + for (int j = 0; j < endPoints.length; j++) + { + assert endPoints[j] == hosts.get((i + j + 1) % hosts.size()); + } + } + } +}