Search in sources :

Example 16 with Multimap

use of com.google.common.collect.Multimap in project titan by thinkaurelius.

the class ElasticSearchIndex method getNewDocument.

public XContentBuilder getNewDocument(final List<IndexEntry> additions, KeyInformation.StoreRetriever informations, int ttl) throws BackendException {
    Preconditions.checkArgument(ttl >= 0);
    try {
        XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
        // JSON writes duplicate fields one after another, which forces us
        // at this stage to make de-duplication on the IndexEntry list. We don't want to pay the
        // price map storage on the Mutation level because non of other backends need that.
        Multimap<String, IndexEntry> uniq = LinkedListMultimap.create();
        for (IndexEntry e : additions) {
            uniq.put(e.field, e);
        }
        for (Map.Entry<String, Collection<IndexEntry>> add : uniq.asMap().entrySet()) {
            KeyInformation keyInformation = informations.get(add.getKey());
            Object value = null;
            switch(keyInformation.getCardinality()) {
                case SINGLE:
                    value = convertToEsType(Iterators.getLast(add.getValue().iterator()).value);
                    break;
                case SET:
                case LIST:
                    value = add.getValue().stream().map(v -> convertToEsType(v.value)).collect(Collectors.toList()).toArray();
                    break;
            }
            builder.field(add.getKey(), value);
            if (hasDualStringMapping(informations.get(add.getKey())) && keyInformation.getDataType() == String.class) {
                builder.field(getDualMappingName(add.getKey()), value);
            }
        }
        if (ttl > 0)
            builder.field(TTL_FIELD, TimeUnit.MILLISECONDS.convert(ttl, TimeUnit.SECONDS));
        builder.endObject();
        return builder;
    } catch (IOException e) {
        throw new PermanentBackendException("Could not write json");
    }
}
Also used : Configuration(com.thinkaurelius.titan.diskstorage.configuration.Configuration) StringUtils(org.apache.commons.lang.StringUtils) SearchHits(org.elasticsearch.search.SearchHits) com.thinkaurelius.titan.diskstorage.indexing(com.thinkaurelius.titan.diskstorage.indexing) AttributeUtil(com.thinkaurelius.titan.graphdb.database.serialize.AttributeUtil) LoggerFactory(org.slf4j.LoggerFactory) Order(com.thinkaurelius.titan.graphdb.internal.Order) XContentBuilder(org.elasticsearch.common.xcontent.XContentBuilder) DeleteRequest(org.elasticsearch.action.delete.DeleteRequest) DefaultTransaction(com.thinkaurelius.titan.diskstorage.util.DefaultTransaction) IndexRequest(org.elasticsearch.action.index.IndexRequest) SearchResponse(org.elasticsearch.action.search.SearchResponse) ConfigOption.disallowEmpty(com.thinkaurelius.titan.diskstorage.configuration.ConfigOption.disallowEmpty) com.thinkaurelius.titan.core.attribute(com.thinkaurelius.titan.core.attribute) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) TitanPredicate(com.thinkaurelius.titan.graphdb.query.TitanPredicate) SearchHit(org.elasticsearch.search.SearchHit) IOUtils(com.thinkaurelius.titan.util.system.IOUtils) ConfigOption(com.thinkaurelius.titan.diskstorage.configuration.ConfigOption) BulkItemResponse(org.elasticsearch.action.bulk.BulkItemResponse) InetSocketTransportAddress(org.elasticsearch.common.transport.InetSocketTransportAddress) BulkResponse(org.elasticsearch.action.bulk.BulkResponse) FieldSortBuilder(org.elasticsearch.search.sort.FieldSortBuilder) Mapping(com.thinkaurelius.titan.core.schema.Mapping) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) CreateIndexResponse(org.elasticsearch.action.admin.indices.create.CreateIndexResponse) Version(org.elasticsearch.Version) org.elasticsearch.index.query(org.elasticsearch.index.query) RestStatus(org.elasticsearch.rest.RestStatus) SortOrder(org.elasticsearch.search.sort.SortOrder) BulkRequestBuilder(org.elasticsearch.action.bulk.BulkRequestBuilder) XContentFactory(org.elasticsearch.common.xcontent.XContentFactory) java.util(java.util) NodeBuilder(org.elasticsearch.node.NodeBuilder) TransportClient(org.elasticsearch.client.transport.TransportClient) PutMappingResponse(org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse) UpdateRequestBuilder(org.elasticsearch.action.update.UpdateRequestBuilder) Cardinality(com.thinkaurelius.titan.core.Cardinality) ImmutableSettings(org.elasticsearch.common.settings.ImmutableSettings) Multimap(com.google.common.collect.Multimap) TitanException(com.thinkaurelius.titan.core.TitanException) Iterators(com.google.common.collect.Iterators) GraphDatabaseConfiguration(com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration) ImmutableList(com.google.common.collect.ImmutableList) Node(org.elasticsearch.node.Node) PreInitializeConfigOptions(com.thinkaurelius.titan.graphdb.configuration.PreInitializeConfigOptions) com.thinkaurelius.titan.graphdb.query.condition(com.thinkaurelius.titan.graphdb.query.condition) DeleteIndexRequest(org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest) Logger(org.slf4j.Logger) Client(org.elasticsearch.client.Client) IndexMissingException(org.elasticsearch.indices.IndexMissingException) IOException(java.io.IOException) ConfigNamespace(com.thinkaurelius.titan.diskstorage.configuration.ConfigNamespace) FileInputStream(java.io.FileInputStream) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) IndicesExistsResponse(org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse) com.thinkaurelius.titan.diskstorage(com.thinkaurelius.titan.diskstorage) DistanceUnit(org.elasticsearch.common.unit.DistanceUnit) SearchRequestBuilder(org.elasticsearch.action.search.SearchRequestBuilder) Preconditions(com.google.common.base.Preconditions) ScriptService(org.elasticsearch.script.ScriptService) IndicesExistsRequest(org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest) IOException(java.io.IOException) XContentBuilder(org.elasticsearch.common.xcontent.XContentBuilder)

Example 17 with Multimap

use of com.google.common.collect.Multimap in project eiger by wlloyd.

the class TransactionProxy method replicateTransactionToOtherDatacenters.

//WL TODO: Remove the assumption that datacenters have matching keyranges
private static void replicateTransactionToOtherDatacenters(MessageProducer producer, String keyspace, ByteBuffer targetKey) throws IOException {
    List<InetAddress> endpoints = StorageService.instance.getLiveNaturalEndpoints(keyspace, targetKey);
    String localDataCenter = DatabaseDescriptor.getEndpointSnitch().getDatacenter(FBUtilities.getBroadcastAddress());
    IWriteResponseHandler ignoredResponseHandler = WriteResponseHandler.create(endpoints, ConsistencyLevel.ALL, keyspace);
    // code follows the structure of StorageProxy.sendToHintedEndpoints
    // Multimap that holds onto all the messages and addresses meant for a specific datacenter
    Map<String, Multimap<Message, InetAddress>> dcMessages = new HashMap<String, Multimap<Message, InetAddress>>(endpoints.size());
    for (InetAddress destination : endpoints) {
        assert FailureDetector.instance.isAlive(destination) : "Not dealing with failed nodes in the dc right now";
        if (destination.equals(FBUtilities.getBroadcastAddress())) {
            //no need to *replicate* to the local machine, it should already have started handling the transaction
            continue;
        }
        if (logger.isDebugEnabled())
            logger.debug("replicate transaction to " + destination);
        String dc = DatabaseDescriptor.getEndpointSnitch().getDatacenter(destination);
        Multimap<Message, InetAddress> messages = dcMessages.get(dc);
        if (messages == null) {
            messages = HashMultimap.create();
            dcMessages.put(dc, messages);
        }
        messages.put(producer.getMessage(Gossiper.instance.getVersion(destination)), destination);
    }
    StorageProxy.sendMessages(localDataCenter, dcMessages, ignoredResponseHandler);
}
Also used : Multimap(com.google.common.collect.Multimap) HashMultimap(com.google.common.collect.HashMultimap) Message(org.apache.cassandra.net.Message) IWriteResponseHandler(org.apache.cassandra.service.IWriteResponseHandler) InetAddress(java.net.InetAddress)

Example 18 with Multimap

use of com.google.common.collect.Multimap in project eiger by wlloyd.

the class StorageProxy method sendMessages.

/**
     * for each datacenter, send a message to one node to relay the write to other replicas
     */
public static void sendMessages(String localDataCenter, Map<String, Multimap<Message, InetAddress>> dcMessages, IWriteResponseHandler handler) throws IOException {
    for (Map.Entry<String, Multimap<Message, InetAddress>> entry : dcMessages.entrySet()) {
        String dataCenter = entry.getKey();
        // send the messages corresponding to this datacenter
        for (Map.Entry<Message, Collection<InetAddress>> messages : entry.getValue().asMap().entrySet()) {
            Message message = messages.getKey();
            // a single message object is used for unhinted writes, so clean out any forwards
            // from previous loop iterations
            message = message.withHeaderRemoved(RowMutation.FORWARD_HEADER);
            Iterator<InetAddress> iter = messages.getValue().iterator();
            InetAddress target = iter.next();
            // direct writes to local DC or old Cassadra versions
            if (dataCenter.equals(localDataCenter) || Gossiper.instance.getVersion(target) < MessagingService.VERSION_11) {
                // yes, the loop and non-loop code here are the same; this is clunky but we want to avoid
                // creating a second iterator since we already have a perfectly good one
                MessagingService.instance().sendRR(message, target, handler);
                while (iter.hasNext()) {
                    target = iter.next();
                    MessagingService.instance().sendRR(message, target, handler);
                }
                continue;
            }
            // Add all the other destinations of the same message as a FORWARD_HEADER entry
            FastByteArrayOutputStream bos = new FastByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(bos);
            dos.writeInt(messages.getValue().size() - 1);
            while (iter.hasNext()) {
                InetAddress destination = iter.next();
                CompactEndpointSerializationHelper.serialize(destination, dos);
                String id = MessagingService.instance().addCallback(handler, message, destination);
                dos.writeUTF(id);
                if (logger.isDebugEnabled())
                    logger.debug("Adding FWD message to: " + destination + " with ID " + id);
            }
            message = message.withHeaderAdded(RowMutation.FORWARD_HEADER, bos.toByteArray());
            // send the combined message + forward headers
            String id = MessagingService.instance().sendRR(message, target, handler);
            if (logger.isDebugEnabled())
                logger.debug("Sending message to: " + target + " with ID " + id);
        }
    }
}
Also used : Multimap(com.google.common.collect.Multimap) HashMultimap(com.google.common.collect.HashMultimap) FastByteArrayOutputStream(org.apache.cassandra.io.util.FastByteArrayOutputStream) DataOutputStream(java.io.DataOutputStream) InetAddress(java.net.InetAddress)

Example 19 with Multimap

use of com.google.common.collect.Multimap in project eiger by wlloyd.

the class MoveTest method testSimultaneousMove.

/*
     * Test ranges and write endpoints when multiple nodes are on the move simultaneously
     */
@Test
public void testSimultaneousMove() throws UnknownHostException, ConfigurationException {
    StorageService ss = StorageService.instance;
    final int RING_SIZE = 10;
    TokenMetadata tmd = ss.getTokenMetadata();
    tmd.clearUnsafe();
    IPartitioner partitioner = new RandomPartitioner();
    VersionedValue.VersionedValueFactory valueFactory = new VersionedValue.VersionedValueFactory(partitioner);
    IPartitioner oldPartitioner = ss.setPartitionerUnsafe(partitioner);
    ArrayList<Token> endpointTokens = new ArrayList<Token>();
    ArrayList<Token> keyTokens = new ArrayList<Token>();
    List<InetAddress> hosts = new ArrayList<InetAddress>();
    // create a ring or 10 nodes
    Util.createInitialRing(ss, partitioner, endpointTokens, keyTokens, hosts, RING_SIZE);
    // nodes 6, 8 and 9 leave
    final int[] MOVING = new int[] { 6, 8, 9 };
    Map<Integer, Token> newTokens = new HashMap<Integer, Token>();
    for (int movingIndex : MOVING) {
        Token newToken = positionToken(movingIndex);
        ss.onChange(hosts.get(movingIndex), ApplicationState.STATUS, valueFactory.moving(newToken));
        // storing token associated with a node index
        newTokens.put(movingIndex, newToken);
    }
    Collection<InetAddress> endpoints;
    tmd = tmd.cloneAfterAllSettled();
    ss.setTokenMetadataUnsafe(tmd);
    // boot two new nodes with keyTokens.get(5) and keyTokens.get(7)
    InetAddress boot1 = InetAddress.getByName("127.0.1.1");
    ss.onChange(boot1, ApplicationState.STATUS, valueFactory.bootstrapping(keyTokens.get(5)));
    InetAddress boot2 = InetAddress.getByName("127.0.1.2");
    ss.onChange(boot2, ApplicationState.STATUS, valueFactory.bootstrapping(keyTokens.get(7)));
    // don't require test update every time a new keyspace is added to test/conf/cassandra.yaml
    Map<String, AbstractReplicationStrategy> tableStrategyMap = new HashMap<String, AbstractReplicationStrategy>();
    for (int i = 1; i <= 4; i++) {
        tableStrategyMap.put("Keyspace" + i, getStrategy("Keyspace" + i, tmd));
    }
    /**
        *  Keyspace1 & Keyspace2 RF=1
        *  {
        *      /127.0.0.1=[(92,0]],
        *      /127.0.0.2=[(0,10]],
        *      /127.0.0.3=[(10,20]],
        *      /127.0.0.4=[(20,30]],
        *      /127.0.0.5=[(30,40]],
        *      /127.0.0.6=[(40,50]],
        *      /127.0.0.7=[(50,62]],
        *      /127.0.0.8=[(62,70]],
        *      /127.0.0.9=[(70,82]],
        *      /127.0.0.10=[(82,92]]
        *  }
        */
    Multimap<InetAddress, Range<Token>> keyspace1ranges = tableStrategyMap.get("Keyspace1").getAddressRanges();
    Collection<Range<Token>> ranges1 = keyspace1ranges.get(InetAddress.getByName("127.0.0.1"));
    assertEquals(collectionSize(ranges1), 1);
    assertTrue(ranges1.iterator().next().equals(generateRange(92, 0)));
    Collection<Range<Token>> ranges2 = keyspace1ranges.get(InetAddress.getByName("127.0.0.2"));
    assertEquals(collectionSize(ranges2), 1);
    assertTrue(ranges2.iterator().next().equals(generateRange(0, 10)));
    Collection<Range<Token>> ranges3 = keyspace1ranges.get(InetAddress.getByName("127.0.0.3"));
    assertEquals(collectionSize(ranges3), 1);
    assertTrue(ranges3.iterator().next().equals(generateRange(10, 20)));
    Collection<Range<Token>> ranges4 = keyspace1ranges.get(InetAddress.getByName("127.0.0.4"));
    assertEquals(collectionSize(ranges4), 1);
    assertTrue(ranges4.iterator().next().equals(generateRange(20, 30)));
    Collection<Range<Token>> ranges5 = keyspace1ranges.get(InetAddress.getByName("127.0.0.5"));
    assertEquals(collectionSize(ranges5), 1);
    assertTrue(ranges5.iterator().next().equals(generateRange(30, 40)));
    Collection<Range<Token>> ranges6 = keyspace1ranges.get(InetAddress.getByName("127.0.0.6"));
    assertEquals(collectionSize(ranges6), 1);
    assertTrue(ranges6.iterator().next().equals(generateRange(40, 50)));
    Collection<Range<Token>> ranges7 = keyspace1ranges.get(InetAddress.getByName("127.0.0.7"));
    assertEquals(collectionSize(ranges7), 1);
    assertTrue(ranges7.iterator().next().equals(generateRange(50, 62)));
    Collection<Range<Token>> ranges8 = keyspace1ranges.get(InetAddress.getByName("127.0.0.8"));
    assertEquals(collectionSize(ranges8), 1);
    assertTrue(ranges8.iterator().next().equals(generateRange(62, 70)));
    Collection<Range<Token>> ranges9 = keyspace1ranges.get(InetAddress.getByName("127.0.0.9"));
    assertEquals(collectionSize(ranges9), 1);
    assertTrue(ranges9.iterator().next().equals(generateRange(70, 82)));
    Collection<Range<Token>> ranges10 = keyspace1ranges.get(InetAddress.getByName("127.0.0.10"));
    assertEquals(collectionSize(ranges10), 1);
    assertTrue(ranges10.iterator().next().equals(generateRange(82, 92)));
    /**
        * Keyspace3 RF=5
        * {
        *      /127.0.0.1=[(92,0], (70,82], (50,62], (82,92], (62,70]],
        *      /127.0.0.2=[(92,0], (70,82], (82,92], (0,10], (62,70]],
        *      /127.0.0.3=[(92,0], (70,82], (82,92], (0,10], (10,20]],
        *      /127.0.0.4=[(92,0], (20,30], (82,92], (0,10], (10,20]],
        *      /127.0.0.5=[(92,0], (30,40], (20,30], (0,10], (10,20]],
        *      /127.0.0.6=[(40,50], (30,40], (20,30], (0,10], (10,20]],
        *      /127.0.0.7=[(40,50], (30,40], (50,62], (20,30], (10,20]],
        *      /127.0.0.8=[(40,50], (30,40], (50,62], (20,30], (62,70]],
        *      /127.0.0.9=[(40,50], (70,82], (30,40], (50,62], (62,70]],
        *      /127.0.0.10=[(40,50], (70,82], (50,62], (82,92], (62,70]]
        * }
        */
    Multimap<InetAddress, Range<Token>> keyspace3ranges = tableStrategyMap.get("Keyspace3").getAddressRanges();
    ranges1 = keyspace3ranges.get(InetAddress.getByName("127.0.0.1"));
    assertEquals(collectionSize(ranges1), 5);
    assertTrue(ranges1.equals(generateRanges(92, 0, 70, 82, 50, 62, 82, 92, 62, 70)));
    ranges2 = keyspace3ranges.get(InetAddress.getByName("127.0.0.2"));
    assertEquals(collectionSize(ranges2), 5);
    assertTrue(ranges2.equals(generateRanges(92, 0, 70, 82, 82, 92, 0, 10, 62, 70)));
    ranges3 = keyspace3ranges.get(InetAddress.getByName("127.0.0.3"));
    assertEquals(collectionSize(ranges3), 5);
    assertTrue(ranges3.equals(generateRanges(92, 0, 70, 82, 82, 92, 0, 10, 10, 20)));
    ranges4 = keyspace3ranges.get(InetAddress.getByName("127.0.0.4"));
    assertEquals(collectionSize(ranges4), 5);
    assertTrue(ranges4.equals(generateRanges(92, 0, 20, 30, 82, 92, 0, 10, 10, 20)));
    ranges5 = keyspace3ranges.get(InetAddress.getByName("127.0.0.5"));
    assertEquals(collectionSize(ranges5), 5);
    assertTrue(ranges5.equals(generateRanges(92, 0, 30, 40, 20, 30, 0, 10, 10, 20)));
    ranges6 = keyspace3ranges.get(InetAddress.getByName("127.0.0.6"));
    assertEquals(collectionSize(ranges6), 5);
    assertTrue(ranges6.equals(generateRanges(40, 50, 30, 40, 20, 30, 0, 10, 10, 20)));
    ranges7 = keyspace3ranges.get(InetAddress.getByName("127.0.0.7"));
    assertEquals(collectionSize(ranges7), 5);
    assertTrue(ranges7.equals(generateRanges(40, 50, 30, 40, 50, 62, 20, 30, 10, 20)));
    ranges8 = keyspace3ranges.get(InetAddress.getByName("127.0.0.8"));
    assertEquals(collectionSize(ranges8), 5);
    assertTrue(ranges8.equals(generateRanges(40, 50, 30, 40, 50, 62, 20, 30, 62, 70)));
    ranges9 = keyspace3ranges.get(InetAddress.getByName("127.0.0.9"));
    assertEquals(collectionSize(ranges9), 5);
    assertTrue(ranges9.equals(generateRanges(40, 50, 70, 82, 30, 40, 50, 62, 62, 70)));
    ranges10 = keyspace3ranges.get(InetAddress.getByName("127.0.0.10"));
    assertEquals(collectionSize(ranges10), 5);
    assertTrue(ranges10.equals(generateRanges(40, 50, 70, 82, 50, 62, 82, 92, 62, 70)));
    /**
         * Keyspace4 RF=3
         * {
         *      /127.0.0.1=[(92,0], (70,82], (82,92]],
         *      /127.0.0.2=[(92,0], (82,92], (0,10]],
         *      /127.0.0.3=[(92,0], (0,10], (10,20]],
         *      /127.0.0.4=[(20,30], (0,10], (10,20]],
         *      /127.0.0.5=[(30,40], (20,30], (10,20]],
         *      /127.0.0.6=[(40,50], (30,40], (20,30]],
         *      /127.0.0.7=[(40,50], (30,40], (50,62]],
         *      /127.0.0.8=[(40,50], (50,62], (62,70]],
         *      /127.0.0.9=[(70,82], (50,62], (62,70]],
         *      /127.0.0.10=[(70,82], (82,92], (62,70]]
         *  }
         */
    Multimap<InetAddress, Range<Token>> keyspace4ranges = tableStrategyMap.get("Keyspace4").getAddressRanges();
    ranges1 = keyspace4ranges.get(InetAddress.getByName("127.0.0.1"));
    assertEquals(collectionSize(ranges1), 3);
    assertTrue(ranges1.equals(generateRanges(92, 0, 70, 82, 82, 92)));
    ranges2 = keyspace4ranges.get(InetAddress.getByName("127.0.0.2"));
    assertEquals(collectionSize(ranges2), 3);
    assertTrue(ranges2.equals(generateRanges(92, 0, 82, 92, 0, 10)));
    ranges3 = keyspace4ranges.get(InetAddress.getByName("127.0.0.3"));
    assertEquals(collectionSize(ranges3), 3);
    assertTrue(ranges3.equals(generateRanges(92, 0, 0, 10, 10, 20)));
    ranges4 = keyspace4ranges.get(InetAddress.getByName("127.0.0.4"));
    assertEquals(collectionSize(ranges4), 3);
    assertTrue(ranges4.equals(generateRanges(20, 30, 0, 10, 10, 20)));
    ranges5 = keyspace4ranges.get(InetAddress.getByName("127.0.0.5"));
    assertEquals(collectionSize(ranges5), 3);
    assertTrue(ranges5.equals(generateRanges(30, 40, 20, 30, 10, 20)));
    ranges6 = keyspace4ranges.get(InetAddress.getByName("127.0.0.6"));
    assertEquals(collectionSize(ranges6), 3);
    assertTrue(ranges6.equals(generateRanges(40, 50, 30, 40, 20, 30)));
    ranges7 = keyspace4ranges.get(InetAddress.getByName("127.0.0.7"));
    assertEquals(collectionSize(ranges7), 3);
    assertTrue(ranges7.equals(generateRanges(40, 50, 30, 40, 50, 62)));
    ranges8 = keyspace4ranges.get(InetAddress.getByName("127.0.0.8"));
    assertEquals(collectionSize(ranges8), 3);
    assertTrue(ranges8.equals(generateRanges(40, 50, 50, 62, 62, 70)));
    ranges9 = keyspace4ranges.get(InetAddress.getByName("127.0.0.9"));
    assertEquals(collectionSize(ranges9), 3);
    assertTrue(ranges9.equals(generateRanges(70, 82, 50, 62, 62, 70)));
    ranges10 = keyspace4ranges.get(InetAddress.getByName("127.0.0.10"));
    assertEquals(collectionSize(ranges10), 3);
    assertTrue(ranges10.equals(generateRanges(70, 82, 82, 92, 62, 70)));
    // pre-calculate the results.
    Map<String, Multimap<Token, InetAddress>> expectedEndpoints = new HashMap<String, Multimap<Token, InetAddress>>();
    expectedEndpoints.put("Keyspace1", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.1.1"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.1.2"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1"));
    expectedEndpoints.put("Keyspace2", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.1.1"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.1.2"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1"));
    expectedEndpoints.put("Keyspace3", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.1.1"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.1.1"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.4"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.put("Keyspace4", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2", "127.0.0.3", "127.0.0.4"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4", "127.0.0.5", "127.0.0.6"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.1.1"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.1.1"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.1.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1", "127.0.0.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1", "127.0.0.2", "127.0.0.3"));
    for (Map.Entry<String, AbstractReplicationStrategy> tableStrategy : tableStrategyMap.entrySet()) {
        String table = tableStrategy.getKey();
        AbstractReplicationStrategy strategy = tableStrategy.getValue();
        for (Token token : keyTokens) {
            endpoints = tmd.getWriteEndpoints(token, table, strategy.getNaturalEndpoints(token));
            assertTrue(expectedEndpoints.get(table).get(token).size() == endpoints.size());
            assertTrue(expectedEndpoints.get(table).get(token).containsAll(endpoints));
        }
        // just to be sure that things still work according to the old tests, run them:
        if (strategy.getReplicationFactor() != 3)
            continue;
        // tokens 5, 15 and 25 should go three nodes
        for (int i = 0; i < 3; i++) {
            endpoints = tmd.getWriteEndpoints(keyTokens.get(i), table, strategy.getNaturalEndpoints(keyTokens.get(i)));
            assertTrue(endpoints.size() == 3);
            assertTrue(endpoints.contains(hosts.get(i + 1)));
            assertTrue(endpoints.contains(hosts.get(i + 2)));
            assertTrue(endpoints.contains(hosts.get(i + 3)));
        }
        // token 35 should go to nodes 4, 5, 6 and boot1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(3), table, strategy.getNaturalEndpoints(keyTokens.get(3)));
        assertTrue(endpoints.size() == 4);
        assertTrue(endpoints.contains(hosts.get(4)));
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(boot1));
        // token 45 should go to nodes 5, 6, 7 boot1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(4), table, strategy.getNaturalEndpoints(keyTokens.get(4)));
        assertTrue(endpoints.size() == 4);
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(boot1));
        // token 55 should go to nodes 6, 7, 8 boot1 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(5), table, strategy.getNaturalEndpoints(keyTokens.get(5)));
        assertTrue(endpoints.size() == 5);
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(boot1));
        assertTrue(endpoints.contains(boot2));
        // token 65 should go to nodes 7, 8, 9 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(6), table, strategy.getNaturalEndpoints(keyTokens.get(6)));
        assertTrue(endpoints.size() == 4);
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(boot2));
        // token 75 should to go nodes 8, 9, 0 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(7), table, strategy.getNaturalEndpoints(keyTokens.get(7)));
        assertTrue(endpoints.size() == 4);
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(boot2));
        // token 85 should go to nodes 9, 0, 1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(8), table, strategy.getNaturalEndpoints(keyTokens.get(8)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        // token 95 should go to nodes 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(9), table, strategy.getNaturalEndpoints(keyTokens.get(9)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
    }
    // all moving nodes are back to the normal state
    for (Integer movingIndex : MOVING) {
        ss.onChange(hosts.get(movingIndex), ApplicationState.STATUS, valueFactory.normal(newTokens.get(movingIndex)));
    }
    ss.setPartitionerUnsafe(oldPartitioner);
}
Also used : VersionedValue(org.apache.cassandra.gms.VersionedValue) TokenMetadata(org.apache.cassandra.locator.TokenMetadata) Multimap(com.google.common.collect.Multimap) HashMultimap(com.google.common.collect.HashMultimap) AbstractReplicationStrategy(org.apache.cassandra.locator.AbstractReplicationStrategy) InetAddress(java.net.InetAddress) Test(org.junit.Test)

Example 20 with Multimap

use of com.google.common.collect.Multimap in project eiger by wlloyd.

the class LeaveAndBootstrapTest method testSimultaneousMove.

/**
     * Test pending ranges and write endpoints when multiple nodes are on the move
     * simultaneously
     */
@Test
public void testSimultaneousMove() throws UnknownHostException, ConfigurationException {
    StorageService ss = StorageService.instance;
    final int RING_SIZE = 10;
    TokenMetadata tmd = ss.getTokenMetadata();
    tmd.clearUnsafe();
    IPartitioner partitioner = new RandomPartitioner();
    VersionedValue.VersionedValueFactory valueFactory = new VersionedValue.VersionedValueFactory(partitioner);
    IPartitioner oldPartitioner = ss.setPartitionerUnsafe(partitioner);
    ArrayList<Token> endpointTokens = new ArrayList<Token>();
    ArrayList<Token> keyTokens = new ArrayList<Token>();
    List<InetAddress> hosts = new ArrayList<InetAddress>();
    // create a ring or 10 nodes
    Util.createInitialRing(ss, partitioner, endpointTokens, keyTokens, hosts, RING_SIZE);
    // nodes 6, 8 and 9 leave
    final int[] LEAVING = new int[] { 6, 8, 9 };
    for (int leaving : LEAVING) ss.onChange(hosts.get(leaving), ApplicationState.STATUS, valueFactory.leaving(endpointTokens.get(leaving)));
    // boot two new nodes with keyTokens.get(5) and keyTokens.get(7)
    InetAddress boot1 = InetAddress.getByName("127.0.1.1");
    ss.onChange(boot1, ApplicationState.STATUS, valueFactory.bootstrapping(keyTokens.get(5)));
    InetAddress boot2 = InetAddress.getByName("127.0.1.2");
    ss.onChange(boot2, ApplicationState.STATUS, valueFactory.bootstrapping(keyTokens.get(7)));
    Collection<InetAddress> endpoints = null;
    /* don't require test update every time a new keyspace is added to test/conf/cassandra.yaml */
    Map<String, AbstractReplicationStrategy> tableStrategyMap = new HashMap<String, AbstractReplicationStrategy>();
    for (int i = 1; i <= 4; i++) {
        tableStrategyMap.put("Keyspace" + i, getStrategy("Keyspace" + i, tmd));
    }
    // pre-calculate the results.
    Map<String, Multimap<Token, InetAddress>> expectedEndpoints = new HashMap<String, Multimap<Token, InetAddress>>();
    expectedEndpoints.put("Keyspace1", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.1.1"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.1.2", "127.0.0.1"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1"));
    expectedEndpoints.get("Keyspace1").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1"));
    expectedEndpoints.put("Keyspace2", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.1.1"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.1.2", "127.0.0.1"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1"));
    expectedEndpoints.get("Keyspace2").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1"));
    expectedEndpoints.put("Keyspace3", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.1.1", "127.0.0.8"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.1.2", "127.0.0.1", "127.0.1.1"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.1.2", "127.0.0.1", "127.0.0.2", "127.0.1.1"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.1.2", "127.0.0.1", "127.0.0.2", "127.0.1.1", "127.0.0.3"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.1.2", "127.0.0.3", "127.0.0.4"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.1.2", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.get("Keyspace3").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.put("Keyspace4", HashMultimap.<Token, InetAddress>create());
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("5"), makeAddrs("127.0.0.2", "127.0.0.3", "127.0.0.4"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("15"), makeAddrs("127.0.0.3", "127.0.0.4", "127.0.0.5"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("25"), makeAddrs("127.0.0.4", "127.0.0.5", "127.0.0.6"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("35"), makeAddrs("127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.1.1", "127.0.0.8"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("45"), makeAddrs("127.0.0.6", "127.0.0.7", "127.0.0.8", "127.0.1.2", "127.0.0.1", "127.0.1.1"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("55"), makeAddrs("127.0.0.7", "127.0.0.8", "127.0.0.9", "127.0.0.1", "127.0.0.2", "127.0.1.1", "127.0.1.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("65"), makeAddrs("127.0.0.8", "127.0.0.9", "127.0.0.10", "127.0.1.2", "127.0.0.1", "127.0.0.2"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("75"), makeAddrs("127.0.0.9", "127.0.0.10", "127.0.0.1", "127.0.1.2", "127.0.0.2", "127.0.0.3"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("85"), makeAddrs("127.0.0.10", "127.0.0.1", "127.0.0.2", "127.0.0.3"));
    expectedEndpoints.get("Keyspace4").putAll(new BigIntegerToken("95"), makeAddrs("127.0.0.1", "127.0.0.2", "127.0.0.3"));
    for (Map.Entry<String, AbstractReplicationStrategy> tableStrategy : tableStrategyMap.entrySet()) {
        String table = tableStrategy.getKey();
        AbstractReplicationStrategy strategy = tableStrategy.getValue();
        for (int i = 0; i < keyTokens.size(); i++) {
            endpoints = tmd.getWriteEndpoints(keyTokens.get(i), table, strategy.getNaturalEndpoints(keyTokens.get(i)));
            assertTrue(expectedEndpoints.get(table).get(keyTokens.get(i)).size() == endpoints.size());
            assertTrue(expectedEndpoints.get(table).get(keyTokens.get(i)).containsAll(endpoints));
        }
        // just to be sure that things still work according to the old tests, run them:
        if (strategy.getReplicationFactor() != 3)
            continue;
        // tokens 5, 15 and 25 should go three nodes
        for (int i = 0; i < 3; ++i) {
            endpoints = tmd.getWriteEndpoints(keyTokens.get(i), table, strategy.getNaturalEndpoints(keyTokens.get(i)));
            assertTrue(endpoints.size() == 3);
            assertTrue(endpoints.contains(hosts.get(i + 1)));
            assertTrue(endpoints.contains(hosts.get(i + 2)));
            assertTrue(endpoints.contains(hosts.get(i + 3)));
        }
        // token 35 should go to nodes 4, 5, 6, 7 and boot1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(3), table, strategy.getNaturalEndpoints(keyTokens.get(3)));
        assertTrue(endpoints.size() == 5);
        assertTrue(endpoints.contains(hosts.get(4)));
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(boot1));
        // token 45 should go to nodes 5, 6, 7, 0, boot1 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(4), table, strategy.getNaturalEndpoints(keyTokens.get(4)));
        assertTrue(endpoints.size() == 6);
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(boot1));
        assertTrue(endpoints.contains(boot2));
        // token 55 should go to nodes 6, 7, 8, 0, 1, boot1 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(5), table, strategy.getNaturalEndpoints(keyTokens.get(5)));
        assertTrue(endpoints.size() == 7);
        assertTrue(endpoints.contains(hosts.get(6)));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(boot1));
        assertTrue(endpoints.contains(boot2));
        // token 65 should go to nodes 7, 8, 9, 0, 1 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(6), table, strategy.getNaturalEndpoints(keyTokens.get(6)));
        assertTrue(endpoints.size() == 6);
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(boot2));
        // token 75 should to go nodes 8, 9, 0, 1, 2 and boot2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(7), table, strategy.getNaturalEndpoints(keyTokens.get(7)));
        assertTrue(endpoints.size() == 6);
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
        assertTrue(endpoints.contains(boot2));
        // token 85 should go to nodes 9, 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(8), table, strategy.getNaturalEndpoints(keyTokens.get(8)));
        assertTrue(endpoints.size() == 4);
        assertTrue(endpoints.contains(hosts.get(9)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
        // token 95 should go to nodes 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(9), table, strategy.getNaturalEndpoints(keyTokens.get(9)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
    }
    // Now finish node 6 and node 9 leaving, as well as boot1 (after this node 8 is still
    // leaving and boot2 in progress
    ss.onChange(hosts.get(LEAVING[0]), ApplicationState.STATUS, valueFactory.left(endpointTokens.get(LEAVING[0]), Gossiper.computeExpireTime()));
    ss.onChange(hosts.get(LEAVING[2]), ApplicationState.STATUS, valueFactory.left(endpointTokens.get(LEAVING[2]), Gossiper.computeExpireTime()));
    ss.onChange(boot1, ApplicationState.STATUS, valueFactory.normal(keyTokens.get(5)));
    // adjust precalcuated results.  this changes what the epected endpoints are.
    expectedEndpoints.get("Keyspace1").get(new BigIntegerToken("55")).removeAll(makeAddrs("127.0.0.7", "127.0.0.8"));
    expectedEndpoints.get("Keyspace1").get(new BigIntegerToken("85")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace2").get(new BigIntegerToken("55")).removeAll(makeAddrs("127.0.0.7", "127.0.0.8"));
    expectedEndpoints.get("Keyspace2").get(new BigIntegerToken("85")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("15")).removeAll(makeAddrs("127.0.0.7", "127.0.0.8"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("25")).removeAll(makeAddrs("127.0.0.7", "127.0.1.2", "127.0.0.1"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("35")).removeAll(makeAddrs("127.0.0.7", "127.0.0.2"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("45")).removeAll(makeAddrs("127.0.0.7", "127.0.0.10", "127.0.0.3"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("55")).removeAll(makeAddrs("127.0.0.7", "127.0.0.10", "127.0.0.4"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("65")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("75")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace3").get(new BigIntegerToken("85")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("35")).removeAll(makeAddrs("127.0.0.7", "127.0.0.8"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("45")).removeAll(makeAddrs("127.0.0.7", "127.0.1.2", "127.0.0.1"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("55")).removeAll(makeAddrs("127.0.0.2", "127.0.0.7"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("65")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("75")).removeAll(makeAddrs("127.0.0.10"));
    expectedEndpoints.get("Keyspace4").get(new BigIntegerToken("85")).removeAll(makeAddrs("127.0.0.10"));
    for (Map.Entry<String, AbstractReplicationStrategy> tableStrategy : tableStrategyMap.entrySet()) {
        String table = tableStrategy.getKey();
        AbstractReplicationStrategy strategy = tableStrategy.getValue();
        for (int i = 0; i < keyTokens.size(); i++) {
            endpoints = tmd.getWriteEndpoints(keyTokens.get(i), table, strategy.getNaturalEndpoints(keyTokens.get(i)));
            assertTrue(expectedEndpoints.get(table).get(keyTokens.get(i)).size() == endpoints.size());
            assertTrue(expectedEndpoints.get(table).get(keyTokens.get(i)).containsAll(endpoints));
        }
        if (strategy.getReplicationFactor() != 3)
            continue;
        // tokens 5, 15 and 25 should go three nodes
        for (int i = 0; i < 3; ++i) {
            endpoints = tmd.getWriteEndpoints(keyTokens.get(i), table, strategy.getNaturalEndpoints(keyTokens.get(i)));
            assertTrue(endpoints.size() == 3);
            assertTrue(endpoints.contains(hosts.get(i + 1)));
            assertTrue(endpoints.contains(hosts.get(i + 2)));
            assertTrue(endpoints.contains(hosts.get(i + 3)));
        }
        // token 35 goes to nodes 4, 5 and boot1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(3), table, strategy.getNaturalEndpoints(keyTokens.get(3)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(4)));
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(boot1));
        // token 45 goes to nodes 5, boot1 and node7
        endpoints = tmd.getWriteEndpoints(keyTokens.get(4), table, strategy.getNaturalEndpoints(keyTokens.get(4)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(5)));
        assertTrue(endpoints.contains(boot1));
        assertTrue(endpoints.contains(hosts.get(7)));
        // token 55 goes to boot1, 7, boot2, 8 and 0
        endpoints = tmd.getWriteEndpoints(keyTokens.get(5), table, strategy.getNaturalEndpoints(keyTokens.get(5)));
        assertTrue(endpoints.size() == 5);
        assertTrue(endpoints.contains(boot1));
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(boot2));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(0)));
        // token 65 goes to nodes 7, boot2, 8, 0 and 1
        endpoints = tmd.getWriteEndpoints(keyTokens.get(6), table, strategy.getNaturalEndpoints(keyTokens.get(6)));
        assertTrue(endpoints.size() == 5);
        assertTrue(endpoints.contains(hosts.get(7)));
        assertTrue(endpoints.contains(boot2));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        // token 75 goes to nodes boot2, 8, 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(7), table, strategy.getNaturalEndpoints(keyTokens.get(7)));
        assertTrue(endpoints.size() == 5);
        assertTrue(endpoints.contains(boot2));
        assertTrue(endpoints.contains(hosts.get(8)));
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
        // token 85 goes to nodes 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(8), table, strategy.getNaturalEndpoints(keyTokens.get(8)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
        // token 95 goes to nodes 0, 1 and 2
        endpoints = tmd.getWriteEndpoints(keyTokens.get(9), table, strategy.getNaturalEndpoints(keyTokens.get(9)));
        assertTrue(endpoints.size() == 3);
        assertTrue(endpoints.contains(hosts.get(0)));
        assertTrue(endpoints.contains(hosts.get(1)));
        assertTrue(endpoints.contains(hosts.get(2)));
    }
    ss.setPartitionerUnsafe(oldPartitioner);
}
Also used : VersionedValue(org.apache.cassandra.gms.VersionedValue) TokenMetadata(org.apache.cassandra.locator.TokenMetadata) Multimap(com.google.common.collect.Multimap) HashMultimap(com.google.common.collect.HashMultimap) AbstractReplicationStrategy(org.apache.cassandra.locator.AbstractReplicationStrategy) InetAddress(java.net.InetAddress) Test(org.junit.Test)

Aggregations

Multimap (com.google.common.collect.Multimap)47 HashMultimap (com.google.common.collect.HashMultimap)16 Test (org.junit.Test)15 List (java.util.List)13 InetAddress (java.net.InetAddress)11 Map (java.util.Map)9 IOException (java.io.IOException)8 ImmutableList (com.google.common.collect.ImmutableList)7 Collection (java.util.Collection)7 ArrayListMultimap (com.google.common.collect.ArrayListMultimap)6 ImmutableMap (com.google.common.collect.ImmutableMap)6 ImmutableMultimap (com.google.common.collect.ImmutableMultimap)6 ArrayList (java.util.ArrayList)6 Set (java.util.Set)6 ImmutableSet (com.google.common.collect.ImmutableSet)5 LinkedListMultimap (com.google.common.collect.LinkedListMultimap)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 Collectors (java.util.stream.Collectors)5 Token (org.apache.cassandra.dht.Token)4 HashMap (java.util.HashMap)3