mirror of https://github.com/apache/cassandra
Remove obsolete OldNetworkTopologyStrategy
Removed the strategy from cqlsh autocomplete, including an array for replication_factor autocomplete that was only used for SimpleStrategy and OldNetworkTopologyStrategy. patch by Pedro Gordo; reviewed by Anthony Grasso, Mick Semb Wever for CASSANDRA-13990
This commit is contained in:
parent
5eea8bf7b5
commit
7c5904753f
|
|
@ -77,3 +77,5 @@ lib/jsr223/scala/*.jar
|
|||
doc/source/configuration/cassandra_config_file.rst
|
||||
doc/source/tools/nodetool
|
||||
|
||||
# Python virtual environment
|
||||
venv/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
4.0-alpha3
|
||||
* Removed obsolete OldNetworkTopologyStrategy (CASSANDRA-13990)
|
||||
* Align record header of FQL and audit binary log (CASSANDRA-15076)
|
||||
* Shuffle forwarding replica for messages to non-local DC (CASSANDRA-15318)
|
||||
* Optimise native protocol ASCII string encoding (CASSANDRA-15410)
|
||||
|
|
|
|||
|
|
@ -175,7 +175,6 @@ The supported @<properties>@ for @CREATE KEYSPACE@ are:
|
|||
The @replication@ @<property>@ is mandatory. It must at least contains the @'class'@ sub-option which defines the replication strategy class to use. The rest of the sub-options depends on that replication strategy class. By default, Cassandra support the following @'class'@:
|
||||
* @'SimpleStrategy'@: A simple strategy that defines a simple replication factor for the whole cluster. The only sub-options supported is @'replication_factor'@ to define that replication factor and is mandatory.
|
||||
* @'NetworkTopologyStrategy'@: A replication strategy that allows to set the replication factor independently for each data-center. The rest of the sub-options are key-value pairs where each time the key is the name of a datacenter and the value the replication factor for that data-center.
|
||||
* @'OldNetworkTopologyStrategy'@: A legacy replication strategy. You should avoid this strategy for new keyspaces and prefer @'NetworkTopologyStrategy'@.
|
||||
|
||||
Attempting to create an already existing keyspace will return an error unless the @IF NOT EXISTS@ option is used. If it is used, the statement will be a no-op if the keyspace already exists.
|
||||
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ def ks_prop_val_mapkey_completer(ctxt, cass):
|
|||
break
|
||||
else:
|
||||
return ["'class'"]
|
||||
if repclass in CqlRuleSet.replication_factor_strategies:
|
||||
if repclass == 'SimpleStrategy':
|
||||
opts = set(('replication_factor',))
|
||||
elif repclass == 'NetworkTopologyStrategy':
|
||||
return [Hint('<dc_name>')]
|
||||
|
|
@ -479,7 +479,7 @@ def ks_prop_val_mapender_completer(ctxt, cass):
|
|||
break
|
||||
else:
|
||||
return [',']
|
||||
if repclass in CqlRuleSet.replication_factor_strategies:
|
||||
if repclass == 'SimpleStrategy':
|
||||
if 'replication_factor' not in keysseen:
|
||||
return [',']
|
||||
if repclass == 'NetworkTopologyStrategy' and len(keysseen) == 1:
|
||||
|
|
|
|||
|
|
@ -41,17 +41,9 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
|
|||
|
||||
replication_strategies = (
|
||||
'SimpleStrategy',
|
||||
'OldNetworkTopologyStrategy',
|
||||
'NetworkTopologyStrategy'
|
||||
)
|
||||
|
||||
replication_factor_strategies = (
|
||||
'SimpleStrategy',
|
||||
'org.apache.cassandra.locator.SimpleStrategy',
|
||||
'OldNetworkTopologyStrategy',
|
||||
'org.apache.cassandra.locator.OldNetworkTopologyStrategy'
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pylexotron.ParsingRuleSet.__init__(self, *args, **kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,127 +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.locator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cassandra.dht.Range;
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.cassandra.dht.Token;
|
||||
|
||||
/**
|
||||
* This Replication Strategy returns the nodes responsible for a given
|
||||
* key but respects rack awareness. It places one replica in a
|
||||
* different data center from the first (if there is any such data center),
|
||||
* the third replica in a different rack in the first datacenter, and
|
||||
* any remaining replicas on the first unused nodes on the ring.
|
||||
*/
|
||||
public class OldNetworkTopologyStrategy extends AbstractReplicationStrategy
|
||||
{
|
||||
private final ReplicationFactor rf;
|
||||
public OldNetworkTopologyStrategy(String keyspaceName, TokenMetadata tokenMetadata, IEndpointSnitch snitch, Map<String, String> configOptions)
|
||||
{
|
||||
super(keyspaceName, tokenMetadata, snitch, configOptions);
|
||||
this.rf = ReplicationFactor.fromString(this.configOptions.get("replication_factor"));
|
||||
}
|
||||
|
||||
public EndpointsForRange calculateNaturalReplicas(Token token, TokenMetadata metadata)
|
||||
{
|
||||
ArrayList<Token> tokens = metadata.sortedTokens();
|
||||
if (tokens.isEmpty())
|
||||
return EndpointsForRange.empty(new Range<>(metadata.partitioner.getMinimumToken(), metadata.partitioner.getMinimumToken()));
|
||||
|
||||
Iterator<Token> iter = TokenMetadata.ringIterator(tokens, token, false);
|
||||
Token primaryToken = iter.next();
|
||||
Token previousToken = metadata.getPredecessor(primaryToken);
|
||||
Range<Token> tokenRange = new Range<>(previousToken, primaryToken);
|
||||
|
||||
EndpointsForRange.Builder replicas = new EndpointsForRange.Builder(tokenRange, rf.allReplicas);
|
||||
|
||||
assert !rf.hasTransientReplicas() : "support transient replicas";
|
||||
replicas.add(new Replica(metadata.getEndpoint(primaryToken), previousToken, primaryToken, true));
|
||||
|
||||
boolean bDataCenter = false;
|
||||
boolean bOtherRack = false;
|
||||
while (replicas.size() < rf.allReplicas && iter.hasNext())
|
||||
{
|
||||
// First try to find one in a different data center
|
||||
Token t = iter.next();
|
||||
if (!snitch.getDatacenter(metadata.getEndpoint(primaryToken)).equals(snitch.getDatacenter(metadata.getEndpoint(t))))
|
||||
{
|
||||
// If we have already found something in a diff datacenter no need to find another
|
||||
if (!bDataCenter)
|
||||
{
|
||||
replicas.add(new Replica(metadata.getEndpoint(t), previousToken, primaryToken, true));
|
||||
bDataCenter = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Now try to find one on a different rack
|
||||
if (!snitch.getRack(metadata.getEndpoint(primaryToken)).equals(snitch.getRack(metadata.getEndpoint(t))) &&
|
||||
snitch.getDatacenter(metadata.getEndpoint(primaryToken)).equals(snitch.getDatacenter(metadata.getEndpoint(t))))
|
||||
{
|
||||
// If we have already found something in a diff rack no need to find another
|
||||
if (!bOtherRack)
|
||||
{
|
||||
replicas.add(new Replica(metadata.getEndpoint(t), previousToken, primaryToken, true));
|
||||
bOtherRack = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we found N number of nodes we are good. This loop wil just exit. Otherwise just
|
||||
// loop through the list and add until we have N nodes.
|
||||
if (replicas.size() < rf.allReplicas)
|
||||
{
|
||||
iter = TokenMetadata.ringIterator(tokens, token, false);
|
||||
while (replicas.size() < rf.allReplicas && iter.hasNext())
|
||||
{
|
||||
Token t = iter.next();
|
||||
Replica replica = new Replica(metadata.getEndpoint(t), previousToken, primaryToken, true);
|
||||
if (!replicas.endpoints().contains(replica.endpoint()))
|
||||
replicas.add(replica);
|
||||
}
|
||||
}
|
||||
|
||||
return replicas.build();
|
||||
}
|
||||
|
||||
public ReplicationFactor getReplicationFactor()
|
||||
{
|
||||
return rf;
|
||||
}
|
||||
|
||||
public void validateOptions() throws ConfigurationException
|
||||
{
|
||||
if (configOptions == null || configOptions.get("replication_factor") == null)
|
||||
{
|
||||
throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option.");
|
||||
}
|
||||
validateReplicationFactor(configOptions.get("replication_factor"));
|
||||
}
|
||||
|
||||
public Collection<String> recognizedOptions()
|
||||
{
|
||||
return Collections.<String>singleton("replication_factor");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,386 +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.locator;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.dht.RandomPartitioner.BigIntegerToken;
|
||||
import org.apache.cassandra.dht.Range;
|
||||
import org.apache.cassandra.dht.Token;
|
||||
import org.apache.cassandra.service.RangeRelocator;
|
||||
import org.apache.cassandra.service.StorageService;
|
||||
import org.apache.cassandra.utils.Pair;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class OldNetworkTopologyStrategyTest
|
||||
{
|
||||
|
||||
private List<Token> keyTokens;
|
||||
private TokenMetadata tmd;
|
||||
private Map<String, ArrayList<InetAddressAndPort>> expectedResults;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupDD()
|
||||
{
|
||||
DatabaseDescriptor.daemonInitialization();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() throws Exception
|
||||
{
|
||||
keyTokens = new ArrayList<Token>();
|
||||
tmd = new TokenMetadata();
|
||||
expectedResults = new HashMap<String, ArrayList<InetAddressAndPort>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 4 same rack endpoints
|
||||
*
|
||||
* @throws java.net.UnknownHostException
|
||||
*/
|
||||
@Test
|
||||
public void testBigIntegerEndpointsA() throws UnknownHostException
|
||||
{
|
||||
RackInferringSnitch endpointSnitch = new RackInferringSnitch();
|
||||
|
||||
AbstractReplicationStrategy strategy = new OldNetworkTopologyStrategy("Keyspace1", tmd, endpointSnitch, optsWithRF(1));
|
||||
addEndpoint("0", "5", "254.0.0.1");
|
||||
addEndpoint("10", "15", "254.0.0.2");
|
||||
addEndpoint("20", "25", "254.0.0.3");
|
||||
addEndpoint("30", "35", "254.0.0.4");
|
||||
|
||||
expectedResults.put("5", buildResult("254.0.0.2", "254.0.0.3", "254.0.0.4"));
|
||||
expectedResults.put("15", buildResult("254.0.0.3", "254.0.0.4", "254.0.0.1"));
|
||||
expectedResults.put("25", buildResult("254.0.0.4", "254.0.0.1", "254.0.0.2"));
|
||||
expectedResults.put("35", buildResult("254.0.0.1", "254.0.0.2", "254.0.0.3"));
|
||||
|
||||
testGetEndpoints(strategy, keyTokens.toArray(new Token[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 3 same rack endpoints
|
||||
* 1 external datacenter
|
||||
*
|
||||
* @throws java.net.UnknownHostException
|
||||
*/
|
||||
@Test
|
||||
public void testBigIntegerEndpointsB() throws UnknownHostException
|
||||
{
|
||||
RackInferringSnitch endpointSnitch = new RackInferringSnitch();
|
||||
|
||||
AbstractReplicationStrategy strategy = new OldNetworkTopologyStrategy("Keyspace1", tmd, endpointSnitch, optsWithRF(1));
|
||||
addEndpoint("0", "5", "254.0.0.1");
|
||||
addEndpoint("10", "15", "254.0.0.2");
|
||||
addEndpoint("20", "25", "254.1.0.3");
|
||||
addEndpoint("30", "35", "254.0.0.4");
|
||||
|
||||
expectedResults.put("5", buildResult("254.0.0.2", "254.1.0.3", "254.0.0.4"));
|
||||
expectedResults.put("15", buildResult("254.1.0.3", "254.0.0.4", "254.0.0.1"));
|
||||
expectedResults.put("25", buildResult("254.0.0.4", "254.1.0.3", "254.0.0.1"));
|
||||
expectedResults.put("35", buildResult("254.0.0.1", "254.1.0.3", "254.0.0.2"));
|
||||
|
||||
testGetEndpoints(strategy, keyTokens.toArray(new Token[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 2 same rack endpoints
|
||||
* 1 same datacenter, different rack endpoints
|
||||
* 1 external datacenter
|
||||
*
|
||||
* @throws java.net.UnknownHostException
|
||||
*/
|
||||
@Test
|
||||
public void testBigIntegerEndpointsC() throws UnknownHostException
|
||||
{
|
||||
RackInferringSnitch endpointSnitch = new RackInferringSnitch();
|
||||
|
||||
AbstractReplicationStrategy strategy = new OldNetworkTopologyStrategy("Keyspace1", tmd, endpointSnitch, optsWithRF(1));
|
||||
addEndpoint("0", "5", "254.0.0.1");
|
||||
addEndpoint("10", "15", "254.0.0.2");
|
||||
addEndpoint("20", "25", "254.0.1.3");
|
||||
addEndpoint("30", "35", "254.1.0.4");
|
||||
|
||||
expectedResults.put("5", buildResult("254.0.0.2", "254.0.1.3", "254.1.0.4"));
|
||||
expectedResults.put("15", buildResult("254.0.1.3", "254.1.0.4", "254.0.0.1"));
|
||||
expectedResults.put("25", buildResult("254.1.0.4", "254.0.0.1", "254.0.0.2"));
|
||||
expectedResults.put("35", buildResult("254.0.0.1", "254.0.1.3", "254.1.0.4"));
|
||||
|
||||
testGetEndpoints(strategy, keyTokens.toArray(new Token[0]));
|
||||
}
|
||||
|
||||
private ArrayList<InetAddressAndPort> buildResult(String... addresses) throws UnknownHostException
|
||||
{
|
||||
ArrayList<InetAddressAndPort> result = new ArrayList<>();
|
||||
for (String address : addresses)
|
||||
{
|
||||
result.add(InetAddressAndPort.getByName(address));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addEndpoint(String endpointTokenID, String keyTokenID, String endpointAddress) throws UnknownHostException
|
||||
{
|
||||
BigIntegerToken endpointToken = new BigIntegerToken(endpointTokenID);
|
||||
|
||||
BigIntegerToken keyToken = new BigIntegerToken(keyTokenID);
|
||||
keyTokens.add(keyToken);
|
||||
|
||||
InetAddressAndPort ep = InetAddressAndPort.getByName(endpointAddress);
|
||||
tmd.updateNormalToken(endpointToken, ep);
|
||||
}
|
||||
|
||||
private void testGetEndpoints(AbstractReplicationStrategy strategy, Token[] keyTokens)
|
||||
{
|
||||
for (Token keyToken : keyTokens)
|
||||
{
|
||||
int j = 0;
|
||||
for (InetAddressAndPort endpoint : strategy.getNaturalReplicasForToken(keyToken).endpoints())
|
||||
{
|
||||
ArrayList<InetAddressAndPort> hostsExpected = expectedResults.get(keyToken.toString());
|
||||
assertEquals(endpoint, hostsExpected.get(j++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test basic methods to move a node. For sure, it's not the best place, but it's easy to test
|
||||
*
|
||||
* @throws java.net.UnknownHostException
|
||||
*/
|
||||
@Test
|
||||
public void testMoveLeft() throws UnknownHostException
|
||||
{
|
||||
// Moves to the left : nothing to fetch, last part to stream
|
||||
|
||||
int movingNodeIdx = 1;
|
||||
BigIntegerToken newToken = new BigIntegerToken("21267647932558653966460912964485513216");
|
||||
BigIntegerToken[] tokens = initTokens();
|
||||
BigIntegerToken[] tokensAfterMove = initTokensAfterMove(tokens, movingNodeIdx, newToken);
|
||||
Pair<Set<Range<Token>>, Set<Range<Token>>> ranges = calculateStreamAndFetchRanges(tokens, tokensAfterMove, movingNodeIdx);
|
||||
|
||||
assertEquals(ranges.left.iterator().next().left, tokensAfterMove[movingNodeIdx]);
|
||||
assertEquals(ranges.left.iterator().next().right, tokens[movingNodeIdx]);
|
||||
assertEquals("No data should be fetched", ranges.right.size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRight() throws UnknownHostException
|
||||
{
|
||||
// Moves to the right : last part to fetch, nothing to stream
|
||||
|
||||
int movingNodeIdx = 1;
|
||||
BigIntegerToken newToken = new BigIntegerToken("35267647932558653966460912964485513216");
|
||||
BigIntegerToken[] tokens = initTokens();
|
||||
BigIntegerToken[] tokensAfterMove = initTokensAfterMove(tokens, movingNodeIdx, newToken);
|
||||
Pair<Set<Range<Token>>, Set<Range<Token>>> ranges = calculateStreamAndFetchRanges(tokens, tokensAfterMove, movingNodeIdx);
|
||||
|
||||
assertEquals("No data should be streamed", ranges.left.size(), 0);
|
||||
assertEquals(ranges.right.iterator().next().left, tokens[movingNodeIdx]);
|
||||
assertEquals(ranges.right.iterator().next().right, tokensAfterMove[movingNodeIdx]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testMoveMiddleOfRing() throws UnknownHostException
|
||||
{
|
||||
// moves to another position in the middle of the ring : should stream all its data, and fetch all its new data
|
||||
|
||||
int movingNodeIdx = 1;
|
||||
int movingNodeIdxAfterMove = 4;
|
||||
BigIntegerToken newToken = new BigIntegerToken("90070591730234615865843651857942052864");
|
||||
BigIntegerToken[] tokens = initTokens();
|
||||
BigIntegerToken[] tokensAfterMove = initTokensAfterMove(tokens, movingNodeIdx, newToken);
|
||||
Pair<Set<Range<Token>>, Set<Range<Token>>> ranges = calculateStreamAndFetchRanges(tokens, tokensAfterMove, movingNodeIdx);
|
||||
|
||||
// sort the results, so they can be compared
|
||||
Range<Token>[] toStream = ranges.left.toArray(new Range[0]);
|
||||
Range<Token>[] toFetch = ranges.right.toArray(new Range[0]);
|
||||
Arrays.sort(toStream);
|
||||
Arrays.sort(toFetch);
|
||||
|
||||
// build expected ranges
|
||||
Range<Token>[] toStreamExpected = new Range[2];
|
||||
toStreamExpected[0] = new Range<Token>(getToken(movingNodeIdx - 2, tokens), getToken(movingNodeIdx - 1, tokens));
|
||||
toStreamExpected[1] = new Range<Token>(getToken(movingNodeIdx - 1, tokens), getToken(movingNodeIdx, tokens));
|
||||
Arrays.sort(toStreamExpected);
|
||||
Range<Token>[] toFetchExpected = new Range[2];
|
||||
toFetchExpected[0] = new Range<Token>(getToken(movingNodeIdxAfterMove - 1, tokens), getToken(movingNodeIdxAfterMove, tokens));
|
||||
toFetchExpected[1] = new Range<Token>(getToken(movingNodeIdxAfterMove, tokensAfterMove), getToken(movingNodeIdx, tokensAfterMove));
|
||||
Arrays.sort(toFetchExpected);
|
||||
|
||||
assertEquals(Arrays.equals(toStream, toStreamExpected), true);
|
||||
assertEquals(Arrays.equals(toFetch, toFetchExpected), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testMoveAfterNextNeighbors() throws UnknownHostException
|
||||
{
|
||||
// moves after its next neighbor in the ring
|
||||
|
||||
int movingNodeIdx = 1;
|
||||
int movingNodeIdxAfterMove = 2;
|
||||
BigIntegerToken newToken = new BigIntegerToken("52535295865117307932921825928971026432");
|
||||
BigIntegerToken[] tokens = initTokens();
|
||||
BigIntegerToken[] tokensAfterMove = initTokensAfterMove(tokens, movingNodeIdx, newToken);
|
||||
Pair<Set<Range<Token>>, Set<Range<Token>>> ranges = calculateStreamAndFetchRanges(tokens, tokensAfterMove, movingNodeIdx);
|
||||
|
||||
|
||||
// sort the results, so they can be compared
|
||||
Range<Token>[] toStream = ranges.left.toArray(new Range[0]);
|
||||
Range<Token>[] toFetch = ranges.right.toArray(new Range[0]);
|
||||
Arrays.sort(toStream);
|
||||
Arrays.sort(toFetch);
|
||||
|
||||
// build expected ranges
|
||||
Range<Token>[] toStreamExpected = new Range[1];
|
||||
toStreamExpected[0] = new Range<Token>(getToken(movingNodeIdx - 2, tokens), getToken(movingNodeIdx - 1, tokens));
|
||||
Arrays.sort(toStreamExpected);
|
||||
Range<Token>[] toFetchExpected = new Range[2];
|
||||
toFetchExpected[0] = new Range<Token>(getToken(movingNodeIdxAfterMove - 1, tokens), getToken(movingNodeIdxAfterMove, tokens));
|
||||
toFetchExpected[1] = new Range<Token>(getToken(movingNodeIdxAfterMove, tokensAfterMove), getToken(movingNodeIdx, tokensAfterMove));
|
||||
Arrays.sort(toFetchExpected);
|
||||
|
||||
assertEquals(Arrays.equals(toStream, toStreamExpected), true);
|
||||
assertEquals(Arrays.equals(toFetch, toFetchExpected), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testMoveBeforePreviousNeighbor() throws UnknownHostException
|
||||
{
|
||||
// moves before its previous neighbor in the ring
|
||||
|
||||
int movingNodeIdx = 1;
|
||||
int movingNodeIdxAfterMove = 7;
|
||||
BigIntegerToken newToken = new BigIntegerToken("158873535527910577765226390751398592512");
|
||||
BigIntegerToken[] tokens = initTokens();
|
||||
BigIntegerToken[] tokensAfterMove = initTokensAfterMove(tokens, movingNodeIdx, newToken);
|
||||
Pair<Set<Range<Token>>, Set<Range<Token>>> ranges = calculateStreamAndFetchRanges(tokens, tokensAfterMove, movingNodeIdx);
|
||||
|
||||
Range<Token>[] toStream = ranges.left.toArray(new Range[0]);
|
||||
Range<Token>[] toFetch = ranges.right.toArray(new Range[0]);
|
||||
Arrays.sort(toStream);
|
||||
Arrays.sort(toFetch);
|
||||
|
||||
Range<Token>[] toStreamExpected = new Range[2];
|
||||
toStreamExpected[0] = new Range<Token>(getToken(movingNodeIdx, tokensAfterMove), getToken(movingNodeIdx - 1, tokensAfterMove));
|
||||
toStreamExpected[1] = new Range<Token>(getToken(movingNodeIdx - 1, tokens), getToken(movingNodeIdx, tokens));
|
||||
Arrays.sort(toStreamExpected);
|
||||
Range<Token>[] toFetchExpected = new Range[1];
|
||||
toFetchExpected[0] = new Range<Token>(getToken(movingNodeIdxAfterMove - 1, tokens), getToken(movingNodeIdxAfterMove, tokens));
|
||||
Arrays.sort(toFetchExpected);
|
||||
|
||||
System.out.println("toStream : " + Arrays.toString(toStream));
|
||||
System.out.println("toFetch : " + Arrays.toString(toFetch));
|
||||
System.out.println("toStreamExpected : " + Arrays.toString(toStreamExpected));
|
||||
System.out.println("toFetchExpected : " + Arrays.toString(toFetchExpected));
|
||||
|
||||
assertEquals(Arrays.equals(toStream, toStreamExpected), true);
|
||||
assertEquals(Arrays.equals(toFetch, toFetchExpected), true);
|
||||
}
|
||||
|
||||
private BigIntegerToken[] initTokensAfterMove(BigIntegerToken[] tokens,
|
||||
int movingNodeIdx, BigIntegerToken newToken)
|
||||
{
|
||||
BigIntegerToken[] tokensAfterMove = tokens.clone();
|
||||
tokensAfterMove[movingNodeIdx] = newToken;
|
||||
return tokensAfterMove;
|
||||
}
|
||||
|
||||
private BigIntegerToken[] initTokens()
|
||||
{
|
||||
BigIntegerToken[] tokens = new BigIntegerToken[] {
|
||||
new BigIntegerToken("0"), // just to be able to test
|
||||
new BigIntegerToken("34028236692093846346337460743176821145"),
|
||||
new BigIntegerToken("42535295865117307932921825928971026432"),
|
||||
new BigIntegerToken("63802943797675961899382738893456539648"),
|
||||
new BigIntegerToken("85070591730234615865843651857942052864"),
|
||||
new BigIntegerToken("106338239662793269832304564822427566080"),
|
||||
new BigIntegerToken("127605887595351923798765477786913079296"),
|
||||
new BigIntegerToken("148873535527910577765226390751398592512")
|
||||
};
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private TokenMetadata initTokenMetadata(BigIntegerToken[] tokens)
|
||||
throws UnknownHostException
|
||||
{
|
||||
TokenMetadata tokenMetadataCurrent = new TokenMetadata();
|
||||
|
||||
int lastIPPart = 1;
|
||||
for (BigIntegerToken token : tokens)
|
||||
tokenMetadataCurrent.updateNormalToken(token, InetAddressAndPort.getByName("254.0.0." + Integer.toString(lastIPPart++)));
|
||||
|
||||
return tokenMetadataCurrent;
|
||||
}
|
||||
|
||||
private BigIntegerToken getToken(int idx, BigIntegerToken[] tokens)
|
||||
{
|
||||
if (idx >= tokens.length)
|
||||
idx = idx % tokens.length;
|
||||
while (idx < 0)
|
||||
idx += tokens.length;
|
||||
|
||||
return tokens[idx];
|
||||
|
||||
}
|
||||
|
||||
private Pair<Set<Range<Token>>, Set<Range<Token>>> calculateStreamAndFetchRanges(BigIntegerToken[] tokens, BigIntegerToken[] tokensAfterMove, int movingNodeIdx) throws UnknownHostException
|
||||
{
|
||||
RackInferringSnitch endpointSnitch = new RackInferringSnitch();
|
||||
|
||||
InetAddressAndPort movingNode = InetAddressAndPort.getByName("254.0.0." + Integer.toString(movingNodeIdx + 1));
|
||||
|
||||
|
||||
TokenMetadata tokenMetadataCurrent = initTokenMetadata(tokens);
|
||||
TokenMetadata tokenMetadataAfterMove = initTokenMetadata(tokensAfterMove);
|
||||
AbstractReplicationStrategy strategy = new OldNetworkTopologyStrategy("Keyspace1", tokenMetadataCurrent, endpointSnitch, optsWithRF(2));
|
||||
|
||||
RangesAtEndpoint currentRanges = strategy.getAddressReplicas().get(movingNode);
|
||||
RangesAtEndpoint updatedRanges = strategy.getPendingAddressRanges(tokenMetadataAfterMove, tokensAfterMove[movingNodeIdx], movingNode);
|
||||
|
||||
return asRanges(RangeRelocator.calculateStreamAndFetchRanges(currentRanges, updatedRanges));
|
||||
}
|
||||
|
||||
private static Map<String, String> optsWithRF(int rf)
|
||||
{
|
||||
return Collections.singletonMap("replication_factor", Integer.toString(rf));
|
||||
}
|
||||
|
||||
public static Pair<Set<Range<Token>>, Set<Range<Token>>> asRanges(Pair<RangesAtEndpoint, RangesAtEndpoint> replicas)
|
||||
{
|
||||
Set<Range<Token>> leftRanges = replicas.left.ranges();
|
||||
Set<Range<Token>> rightRanges = replicas.right.ranges();
|
||||
return Pair.create(leftRanges, rightRanges);
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +67,6 @@ public class ReplicationStrategyEndpointCacheTest
|
|||
public void testEndpointsWereCached() throws Exception
|
||||
{
|
||||
runEndpointsWereCachedTest(FakeSimpleStrategy.class, null);
|
||||
runEndpointsWereCachedTest(FakeOldNetworkTopologyStrategy.class, null);
|
||||
runEndpointsWereCachedTest(FakeNetworkTopologyStrategy.class, new HashMap<String, String>());
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +80,6 @@ public class ReplicationStrategyEndpointCacheTest
|
|||
public void testCacheRespectsTokenChanges() throws Exception
|
||||
{
|
||||
runCacheRespectsTokenChangesTest(SimpleStrategy.class, null);
|
||||
runCacheRespectsTokenChangesTest(OldNetworkTopologyStrategy.class, null);
|
||||
runCacheRespectsTokenChangesTest(NetworkTopologyStrategy.class, new HashMap<String, String>());
|
||||
}
|
||||
|
||||
|
|
@ -135,23 +133,6 @@ public class ReplicationStrategyEndpointCacheTest
|
|||
}
|
||||
}
|
||||
|
||||
protected static class FakeOldNetworkTopologyStrategy extends OldNetworkTopologyStrategy
|
||||
{
|
||||
private boolean called = false;
|
||||
|
||||
public FakeOldNetworkTopologyStrategy(String keyspaceName, TokenMetadata tokenMetadata, IEndpointSnitch snitch, Map<String, String> configOptions)
|
||||
{
|
||||
super(keyspaceName, tokenMetadata, snitch, configOptions);
|
||||
}
|
||||
|
||||
public EndpointsForRange calculateNaturalReplicas(Token token, TokenMetadata metadata)
|
||||
{
|
||||
assert !called : "calculateNaturalReplicas was already called, result should have been cached";
|
||||
called = true;
|
||||
return super.calculateNaturalReplicas(token, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class FakeNetworkTopologyStrategy extends NetworkTopologyStrategy
|
||||
{
|
||||
private boolean called = false;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import org.apache.cassandra.db.marshal.UTF8Type;
|
|||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.cassandra.io.sstable.Component;
|
||||
import org.apache.cassandra.io.sstable.Descriptor;
|
||||
import org.apache.cassandra.locator.OldNetworkTopologyStrategy;
|
||||
import org.apache.cassandra.locator.NetworkTopologyStrategy;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
|
||||
import static org.apache.cassandra.Util.throwAssert;
|
||||
|
|
@ -385,7 +385,7 @@ public class MigrationManagerTest
|
|||
}
|
||||
|
||||
Map<String, String> replicationMap = new HashMap<>();
|
||||
replicationMap.put(ReplicationParams.CLASS, OldNetworkTopologyStrategy.class.getName());
|
||||
replicationMap.put(ReplicationParams.CLASS, NetworkTopologyStrategy.class.getName());
|
||||
replicationMap.put("replication_factor", "1");
|
||||
|
||||
KeyspaceMetadata newKs = KeyspaceMetadata.create(cf.keyspace, KeyspaceParams.create(true, replicationMap));
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ public class BootstrapTransientTest
|
|||
true,
|
||||
tmds.left,
|
||||
tmds.right,
|
||||
"OldNetworkTopologyStrategyTest",
|
||||
"TestKeyspace",
|
||||
sourceFilters);
|
||||
result.asMap().forEach((replica, list) -> System.out.printf("Replica %s, sources %s%n", replica, list));
|
||||
assertMultimapEqualsIgnoreOrder(expectedResult, result);
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ public class MoveTransientTest
|
|||
true,
|
||||
tmds.left,
|
||||
tmds.right,
|
||||
"OldNetworkTopologyStrategyTest",
|
||||
"TestKeyspace",
|
||||
sourceFilters);
|
||||
logger.info("Ranges to fetch with preferred endpoints");
|
||||
logger.info(result.toString());
|
||||
|
|
|
|||
Loading…
Reference in New Issue