You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by tf...@apache.org on 2017/05/12 23:39:20 UTC

[53/58] [abbrv] lucene-solr:jira/solr-10233: Rename replica types

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java b/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java
new file mode 100644
index 0000000..57f25d0
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java
@@ -0,0 +1,829 @@
+/*
+ * 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.solr.cloud;
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.http.client.HttpClient;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.util.LuceneTestCase.Slow;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.CollectionStatePredicate;
+import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.update.DirectUpdateHandler2;
+import org.apache.solr.update.SolrIndexWriter;
+import org.apache.solr.update.UpdateHandler;
+import org.apache.solr.update.UpdateLog;
+import org.apache.solr.util.RefCounted;
+import org.apache.solr.util.TestInjection;
+import org.apache.solr.util.TimeOut;
+import org.apache.zookeeper.KeeperException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+
+@Slow
+public class TestTlogReplica extends SolrCloudTestCase {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  
+  private String collectionName = null;
+  private final static int REPLICATION_TIMEOUT_SECS = 10;
+  
+  private String suggestedCollectionName() {
+    return (getTestClass().getSimpleName().replace("Test", "") + "_" + getTestName().split(" ")[0]).replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase(Locale.ROOT);
+  }
+
+  @BeforeClass
+  public static void setupCluster() throws Exception {
+    TestInjection.waitForReplicasInSync = null; // We'll be explicit about this in this test
+    configureCluster(2) // 2 + random().nextInt(3) 
+        .addConfig("conf", configset("cloud-minimal-inplace-updates"))
+        .configure();
+    Boolean useLegacyCloud = rarely();
+    LOG.info("Using legacyCloud?: {}", useLegacyCloud);
+    CollectionAdminRequest.ClusterProp clusterPropRequest = CollectionAdminRequest.setClusterProperty(ZkStateReader.LEGACY_CLOUD, String.valueOf(useLegacyCloud));
+    CollectionAdminResponse response = clusterPropRequest.process(cluster.getSolrClient());
+    assertEquals(0, response.getStatus());
+  }
+  
+  @AfterClass
+  public static void tearDownCluster() {
+    TestInjection.reset();
+  }
+  
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    collectionName = suggestedCollectionName();
+    expectThrows(SolrException.class, () -> getCollectionState(collectionName));
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    for (JettySolrRunner jetty:cluster.getJettySolrRunners()) {
+      if (!jetty.isRunning()) {
+        LOG.warn("Jetty {} not running, probably some bad test. Starting it", jetty.getLocalPort());
+        ChaosMonkey.start(jetty);
+      }
+    }
+    if (cluster.getSolrClient().getZkStateReader().getClusterState().getCollectionOrNull(collectionName) != null) {
+      LOG.info("tearDown deleting collection");
+      CollectionAdminRequest.deleteCollection(collectionName).process(cluster.getSolrClient());
+      waitForDeletion(collectionName);
+    }
+    super.tearDown();
+  }
+  
+  /**
+   * Asserts that Update logs exist for replicas of type {@link org.apache.solr.common.cloud.Replica.Type#NRT}, but not
+   * for replicas of type {@link org.apache.solr.common.cloud.Replica.Type#PULL}
+   */
+  private void assertUlogPresence(DocCollection collection) {
+    for (Slice s:collection.getSlices()) {
+      for (Replica r:s.getReplicas()) {
+        SolrCore core = null;
+        try {
+          core = cluster.getReplicaJetty(r).getCoreContainer().getCore(r.getCoreName());
+          assertNotNull(core);
+          assertTrue("Update log should exist for replicas of type Append", 
+              new java.io.File(core.getUlogDir()).exists());
+        } finally {
+          core.close();
+        }
+      }
+    }
+  }
+  
+  @Repeat(iterations=2) // 2 times to make sure cleanup is complete and we can create the same collection
+  public void testCreateDelete() throws Exception {
+    try {
+      CollectionAdminRequest.createCollection(collectionName, "conf", 2, 0, 4, 0)
+      .setMaxShardsPerNode(100)
+      .process(cluster.getSolrClient());
+      DocCollection docCollection = getCollectionState(collectionName);
+      assertNotNull(docCollection);
+      assertEquals("Expecting 2 shards",
+          2, docCollection.getSlices().size());
+      assertEquals("Expecting 4 relpicas per shard",
+          8, docCollection.getReplicas().size());
+      assertEquals("Expecting 8 tlog replicas, 4 per shard",
+          8, docCollection.getReplicas(EnumSet.of(Replica.Type.TLOG)).size());
+      assertEquals("Expecting no nrt replicas",
+          0, docCollection.getReplicas(EnumSet.of(Replica.Type.NRT)).size());
+      assertEquals("Expecting no pull replicas",
+          0, docCollection.getReplicas(EnumSet.of(Replica.Type.PULL)).size());
+      for (Slice s:docCollection.getSlices()) {
+        assertTrue(s.getLeader().getType() == Replica.Type.TLOG);
+        List<String> shardElectionNodes = cluster.getZkClient().getChildren(ZkStateReader.getShardLeadersElectPath(collectionName, s.getName()), null, true);
+        assertEquals("Unexpected election nodes for Shard: " + s.getName() + ": " + Arrays.toString(shardElectionNodes.toArray()), 
+            4, shardElectionNodes.size());
+      }
+      assertUlogPresence(docCollection);
+    } finally {
+      zkClient().printLayoutToStdOut();
+    }
+  }
+  
+  @SuppressWarnings("unchecked")
+  public void testAddDocs() throws Exception {
+    int numTlogReplicas = 1 + random().nextInt(3);
+    DocCollection docCollection = createAndWaitForCollection(1, 0, numTlogReplicas, 0);
+    assertEquals(1, docCollection.getSlices().size());
+    
+    cluster.getSolrClient().add(collectionName, new SolrInputDocument("id", "1", "foo", "bar"));
+    cluster.getSolrClient().commit(collectionName);
+    
+    Slice s = docCollection.getSlices().iterator().next();
+    try (HttpSolrClient leaderClient = getHttpSolrClient(s.getLeader().getCoreUrl())) {
+      assertEquals(1, leaderClient.query(new SolrQuery("*:*")).getResults().getNumFound());
+    }
+    
+    TimeOut t = new TimeOut(REPLICATION_TIMEOUT_SECS, TimeUnit.SECONDS);
+    for (Replica r:s.getReplicas(EnumSet.of(Replica.Type.TLOG))) {
+      //TODO: assert replication < REPLICATION_TIMEOUT_SECS
+      try (HttpSolrClient tlogReplicaClient = getHttpSolrClient(r.getCoreUrl())) {
+        while (true) {
+          try {
+            assertEquals("Replica " + r.getName() + " not up to date after 10 seconds",
+                1, tlogReplicaClient.query(new SolrQuery("*:*")).getResults().getNumFound());
+            // Append replicas process all updates
+            SolrQuery req = new SolrQuery(
+                "qt", "/admin/plugins",
+                "stats", "true");
+            QueryResponse statsResponse = tlogReplicaClient.query(req);
+            assertEquals("Append replicas should recive all updates. Replica: " + r + ", response: " + statsResponse, 
+                1L, ((Map<String, Object>)((NamedList<Object>)statsResponse.getResponse()).findRecursive("plugins", "UPDATE", "updateHandler", "stats")).get("UPDATE.updateHandler.cumulativeAdds.count"));
+            break;
+          } catch (AssertionError e) {
+            if (t.hasTimedOut()) {
+              throw e;
+            } else {
+              Thread.sleep(100);
+            }
+          }
+        }
+      }
+    }
+    assertUlogPresence(docCollection);
+  }
+  
+  public void testAddRemoveTlogReplica() throws Exception {
+    DocCollection docCollection = createAndWaitForCollection(2, 0, 1, 0);
+    assertEquals(2, docCollection.getSlices().size());
+    
+    CollectionAdminRequest.addReplicaToShard(collectionName, "shard1", Replica.Type.TLOG).process(cluster.getSolrClient());
+    docCollection = assertNumberOfReplicas(0, 3, 0, true, false);
+    CollectionAdminRequest.addReplicaToShard(collectionName, "shard2", Replica.Type.TLOG).process(cluster.getSolrClient());    
+    docCollection = assertNumberOfReplicas(0, 4, 0, true, false);
+    
+    waitForState("Expecting collection to have 2 shards and 2 replica each", collectionName, clusterShape(2, 2));
+    
+    //Delete pull replica from shard1
+    CollectionAdminRequest.deleteReplica(
+        collectionName, 
+        "shard1", 
+        docCollection.getSlice("shard1").getReplicas(EnumSet.of(Replica.Type.TLOG)).get(0).getName())
+    .process(cluster.getSolrClient());
+    assertNumberOfReplicas(0, 3, 0, true, true);
+  }
+  
+  public void testRemoveLeader() throws Exception {
+    doReplaceLeader(true);
+  }
+  
+  public void testKillLeader() throws Exception {
+    doReplaceLeader(false);
+  }
+  
+  public void testRealTimeGet() throws SolrServerException, IOException, KeeperException, InterruptedException {
+    // should be redirected to Replica.Type.REALTIME
+    int numReplicas = random().nextBoolean()?1:2;
+    int numNrtReplicas = random().nextBoolean()?0:2;
+    CollectionAdminRequest.createCollection(collectionName, "conf", 1, numNrtReplicas, numReplicas, 0)
+      .setMaxShardsPerNode(100)
+      .process(cluster.getSolrClient());
+    waitForState("Unexpected replica count", collectionName, activeReplicaCount(numNrtReplicas, numReplicas, 0));
+    DocCollection docCollection = assertNumberOfReplicas(numNrtReplicas, numReplicas, 0, false, true);
+    HttpClient httpClient = cluster.getSolrClient().getHttpClient();
+    int id = 0;
+    Slice slice = docCollection.getSlice("shard1");
+    List<String> ids = new ArrayList<>(slice.getReplicas().size());
+    for (Replica rAdd:slice.getReplicas()) {
+      try (HttpSolrClient client = getHttpSolrClient(rAdd.getCoreUrl(), httpClient)) {
+        client.add(new SolrInputDocument("id", String.valueOf(id), "foo_s", "bar"));
+      }
+      SolrDocument docCloudClient = cluster.getSolrClient().getById(collectionName, String.valueOf(id));
+      assertEquals("bar", docCloudClient.getFieldValue("foo_s"));
+      for (Replica rGet:slice.getReplicas()) {
+        try (HttpSolrClient client = getHttpSolrClient(rGet.getCoreUrl(), httpClient)) {
+          SolrDocument doc = client.getById(String.valueOf(id));
+          assertEquals("bar", doc.getFieldValue("foo_s"));
+        }
+      }
+      ids.add(String.valueOf(id));
+      id++;
+    }
+    SolrDocumentList previousAllIdsResult = null;
+    for (Replica rAdd:slice.getReplicas()) {
+      try (HttpSolrClient client = getHttpSolrClient(rAdd.getCoreUrl(), httpClient)) {
+        SolrDocumentList allIdsResult = client.getById(ids);
+        if (previousAllIdsResult != null) {
+          assertTrue(compareSolrDocumentList(previousAllIdsResult, allIdsResult));
+        } else {
+          // set the first response here
+          previousAllIdsResult = allIdsResult;
+          assertEquals("Unexpected number of documents", ids.size(), allIdsResult.getNumFound());
+        }
+      }
+      id++;
+    }
+  }
+  
+  /*
+   * validate leader election and that replication still happens on a new leader
+   */
+  private void doReplaceLeader(boolean removeReplica) throws Exception {
+    DocCollection docCollection = createAndWaitForCollection(1, 0, 2, 0);
+    
+    // Add a document and commit
+    cluster.getSolrClient().add(collectionName, new SolrInputDocument("id", "1", "foo", "bar"));
+    cluster.getSolrClient().commit(collectionName);
+    Slice s = docCollection.getSlices().iterator().next();
+    try (HttpSolrClient leaderClient = getHttpSolrClient(s.getLeader().getCoreUrl())) {
+      assertEquals(1, leaderClient.query(new SolrQuery("*:*")).getResults().getNumFound());
+    }
+    
+    waitForNumDocsInAllReplicas(1, docCollection.getReplicas(EnumSet.of(Replica.Type.TLOG)), REPLICATION_TIMEOUT_SECS);
+    
+    // Delete leader replica from shard1
+    JettySolrRunner leaderJetty = null;
+    if (removeReplica) {
+      CollectionAdminRequest.deleteReplica(
+          collectionName, 
+          "shard1", 
+          s.getLeader().getName())
+      .process(cluster.getSolrClient());
+    } else {
+      leaderJetty = cluster.getReplicaJetty(s.getLeader());
+      ChaosMonkey.kill(leaderJetty);
+      waitForState("Leader replica not removed", collectionName, clusterShape(1, 1));
+      // Wait for cluster state to be updated
+      waitForState("Replica state not updated in cluster state", 
+          collectionName, clusterStateReflectsActiveAndDownReplicas());
+    }
+    docCollection = assertNumberOfReplicas(0, 1, 0, true, true);
+    
+    // Wait until a new leader is elected
+    TimeOut t = new TimeOut(30, TimeUnit.SECONDS);
+    while (!t.hasTimedOut()) {
+      docCollection = getCollectionState(collectionName);
+      Replica leader = docCollection.getSlice("shard1").getLeader();
+      if (leader != null && leader.isActive(cluster.getSolrClient().getZkStateReader().getClusterState().getLiveNodes())) {
+        break;
+      }
+      Thread.sleep(500);
+    }
+    assertFalse("Timeout waiting for a new leader to be elected", t.hasTimedOut());
+    
+    // There is a new leader, I should be able to add and commit
+    cluster.getSolrClient().add(collectionName, new SolrInputDocument("id", "2", "foo", "zoo"));
+    cluster.getSolrClient().commit(collectionName);
+    
+    // Queries should still work
+    waitForNumDocsInAllReplicas(2, docCollection.getReplicas(EnumSet.of(Replica.Type.TLOG)), REPLICATION_TIMEOUT_SECS);
+    // Start back the node
+    if (removeReplica) {
+      CollectionAdminRequest.addReplicaToShard(collectionName, "shard1", Replica.Type.TLOG).process(cluster.getSolrClient());
+    } else {
+      ChaosMonkey.start(leaderJetty);
+    }
+    waitForState("Expected collection to be 1x2", collectionName, clusterShape(1, 2));
+    // added replica should replicate from the leader
+    waitForNumDocsInAllReplicas(2, docCollection.getReplicas(EnumSet.of(Replica.Type.TLOG)), REPLICATION_TIMEOUT_SECS);
+  }
+  
+  public void testKillTlogReplica() throws Exception {
+    DocCollection docCollection = createAndWaitForCollection(1, 0, 2, 0);
+    
+    waitForNumDocsInAllActiveReplicas(0);
+    cluster.getSolrClient().add(collectionName, new SolrInputDocument("id", "1", "foo", "bar"));
+    cluster.getSolrClient().commit(collectionName);
+    waitForNumDocsInAllActiveReplicas(1);
+    
+    JettySolrRunner pullReplicaJetty = cluster.getReplicaJetty(docCollection.getSlice("shard1").getReplicas(EnumSet.of(Replica.Type.TLOG)).get(0));
+    ChaosMonkey.kill(pullReplicaJetty);
+    waitForState("Replica not removed", collectionName, activeReplicaCount(0, 1, 0));
+    // Also wait for the replica to be placed in state="down"
+    waitForState("Didn't update state", collectionName, clusterStateReflectsActiveAndDownReplicas());
+    
+    cluster.getSolrClient().add(collectionName, new SolrInputDocument("id", "2", "foo", "bar"));
+    cluster.getSolrClient().commit(collectionName);
+    waitForNumDocsInAllActiveReplicas(2);
+    
+    ChaosMonkey.start(pullReplicaJetty);
+    waitForState("Replica not added", collectionName, activeReplicaCount(0, 2, 0));
+    waitForNumDocsInAllActiveReplicas(2);
+  }
+  
+  public void testSearchWhileReplicationHappens() {
+      
+  }
+  
+  public void testReplication() {
+    // Validate incremental replication
+  }
+  
+  public void testOnlyLeaderIndexes() throws Exception {
+    createAndWaitForCollection(1, 0, 2, 0);
+    
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    new UpdateRequest()
+        .add(sdoc("id", "1"))
+        .add(sdoc("id", "2"))
+        .add(sdoc("id", "3"))
+        .add(sdoc("id", "4"))
+        .process(cloudClient, collectionName);
+
+    {
+      UpdateHandler updateHandler = getSolrCore(true).get(0).getUpdateHandler();
+      RefCounted<IndexWriter> iwRef = updateHandler.getSolrCoreState().getIndexWriter(null);
+      assertTrue("IndexWriter at leader must see updates ", iwRef.get().hasUncommittedChanges());
+      iwRef.decref();
+    }
+
+    for (SolrCore solrCore : getSolrCore(false)) {
+      RefCounted<IndexWriter> iwRef = solrCore.getUpdateHandler().getSolrCoreState().getIndexWriter(null);
+      assertFalse("IndexWriter at replicas must not see updates ", iwRef.get().hasUncommittedChanges());
+      iwRef.decref();
+    }
+
+    checkRTG(1, 4, cluster.getJettySolrRunners());
+
+    new UpdateRequest()
+        .deleteById("1")
+        .deleteByQuery("id:2")
+        .process(cloudClient, collectionName);
+
+    // The DBQ is not processed at replicas, so we still can get doc2 and other docs by RTG
+    checkRTG(2,4, getSolrRunner(false));
+
+    new UpdateRequest()
+        .commit(cloudClient, collectionName);
+
+    waitForNumDocsInAllActiveReplicas(2);
+
+    // Update log roll over
+    for (SolrCore solrCore : getSolrCore(false)) {
+      UpdateLog updateLog = solrCore.getUpdateHandler().getUpdateLog();
+      assertFalse(updateLog.hasUncommittedChanges());
+    }
+
+    // UpdateLog copy over old updates
+    for (int i = 15; i <= 150; i++) {
+      cloudClient.add(collectionName, sdoc("id",String.valueOf(i)));
+      if (random().nextInt(100) < 15 & i != 150) {
+        cloudClient.commit(collectionName);
+      }
+    }
+    checkRTG(120,150, cluster.getJettySolrRunners());
+    waitForReplicasCatchUp(20);
+  }
+  
+  public void testRecovery() throws Exception {
+    boolean useKill = random().nextBoolean();
+    createAndWaitForCollection(1, 0, 2, 0);
+    
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    new UpdateRequest()
+        .add(sdoc("id", "3"))
+        .add(sdoc("id", "4"))
+        .commit(cloudClient, collectionName);
+    // Replica recovery
+    new UpdateRequest()
+        .add(sdoc("id", "5"))
+        .process(cloudClient, collectionName);
+    JettySolrRunner solrRunner = getSolrRunner(false).get(0);
+    if (useKill) { 
+      ChaosMonkey.kill(solrRunner);
+    } else {
+      ChaosMonkey.stop(solrRunner);
+    }
+    new UpdateRequest()
+        .add(sdoc("id", "6"))
+        .process(cloudClient, collectionName);
+    ChaosMonkey.start(solrRunner);
+    waitForState("Replica didn't recover", collectionName, activeReplicaCount(0,2,0));
+    // We skip peerSync, so replica will always trigger commit on leader
+    waitForNumDocsInAllActiveReplicas(4);
+    
+    // If I add the doc immediately, the leader fails to communicate with the follower with broken pipe. Related to SOLR-9555 I believe
+    //nocommit
+    Thread.sleep(10000);
+    
+    // More Replica recovery testing
+    new UpdateRequest()
+        .add(sdoc("id", "7"))
+        .process(cloudClient, collectionName);
+    checkRTG(3,7, cluster.getJettySolrRunners());
+    DirectUpdateHandler2.commitOnClose = false;
+    ChaosMonkey.stop(solrRunner);
+    DirectUpdateHandler2.commitOnClose = true;
+    ChaosMonkey.start(solrRunner);
+    waitForState("Replica didn't recover", collectionName, activeReplicaCount(0,2,0));
+    checkRTG(3,7, cluster.getJettySolrRunners());
+    waitForNumDocsInAllActiveReplicas(5, 0);
+
+    // Test replica recovery apply buffer updates
+    Semaphore waitingForBufferUpdates = new Semaphore(0);
+    Semaphore waitingForReplay = new Semaphore(0);
+    RecoveryStrategy.testing_beforeReplayBufferingUpdates = () -> {
+      try {
+        waitingForReplay.release();
+        waitingForBufferUpdates.acquire();
+      } catch (InterruptedException e) {
+        e.printStackTrace();
+        fail("Test interrupted: " + e.getMessage());
+      }
+    };
+    if (useKill) { 
+      ChaosMonkey.kill(solrRunner);
+    } else {
+      ChaosMonkey.stop(solrRunner);
+    }
+    ChaosMonkey.start(solrRunner);
+    waitingForReplay.acquire();
+    new UpdateRequest()
+        .add(sdoc("id", "8"))
+        .add(sdoc("id", "9"))
+        .process(cloudClient, collectionName);
+    waitingForBufferUpdates.release();
+    RecoveryStrategy.testing_beforeReplayBufferingUpdates = null;
+    waitForState("Replica didn't recover", collectionName, activeReplicaCount(0,2,0));
+    checkRTG(3,9, cluster.getJettySolrRunners());
+    waitForNumDocsInAllActiveReplicas(5, 0);
+    for (SolrCore solrCore : getSolrCore(false)) {
+      RefCounted<IndexWriter> iwRef = solrCore.getUpdateHandler().getSolrCoreState().getIndexWriter(null);
+      assertFalse("IndexWriter at replicas must not see updates ", iwRef.get().hasUncommittedChanges());
+      iwRef.decref();
+    }
+  }
+  
+  public void testDeleteById() throws Exception{
+    createAndWaitForCollection(1,0,2,0);
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    new UpdateRequest()
+        .deleteByQuery("*:*")
+        .commit(cluster.getSolrClient(), collectionName);
+    new UpdateRequest()
+        .add(sdoc("id", "1"))
+        .commit(cloudClient, collectionName);
+    waitForNumDocsInAllActiveReplicas(1);
+    new UpdateRequest()
+        .deleteById("1")
+        .process(cloudClient, collectionName);
+    boolean successs = false;
+    try {
+      checkRTG(1, 1, cluster.getJettySolrRunners());
+      successs = true;
+    } catch (AssertionError e) {
+      //expected
+    }
+    assertFalse("Doc1 is deleted but it's still exist", successs);
+  }
+  
+  public void testBasicLeaderElection() throws Exception {
+    createAndWaitForCollection(1,0,2,0);
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    new UpdateRequest()
+        .deleteByQuery("*:*")
+        .commit(cluster.getSolrClient(), collectionName);
+    new UpdateRequest()
+        .add(sdoc("id", "1"))
+        .add(sdoc("id", "2"))
+        .process(cloudClient, collectionName);
+    JettySolrRunner oldLeaderJetty = getSolrRunner(true).get(0);
+    ChaosMonkey.kill(oldLeaderJetty);
+    waitForState("Replica not removed", collectionName, activeReplicaCount(0, 1, 0));
+    new UpdateRequest()
+        .add(sdoc("id", "3"))
+        .add(sdoc("id", "4"))
+        .process(cloudClient, collectionName);
+    ChaosMonkey.start(oldLeaderJetty);
+    waitForState("Replica not added", collectionName, activeReplicaCount(0, 2, 0));
+    checkRTG(1,4, cluster.getJettySolrRunners());
+    new UpdateRequest()
+        .commit(cloudClient, collectionName);
+    waitForNumDocsInAllActiveReplicas(4, 0);
+  }
+  
+  public void testOutOfOrderDBQWithInPlaceUpdates() throws Exception {
+    createAndWaitForCollection(1,0,2,0);
+    assertFalse(getSolrCore(true).get(0).getLatestSchema().getField("inplace_updatable_int").indexed());
+    assertFalse(getSolrCore(true).get(0).getLatestSchema().getField("inplace_updatable_int").stored());
+    assertTrue(getSolrCore(true).get(0).getLatestSchema().getField("inplace_updatable_int").hasDocValues());
+    List<UpdateRequest> updates = new ArrayList<>();
+    updates.add(simulatedUpdateRequest(null, "id", 1, "title_s", "title0_new", "inplace_updatable_int", 5, "_version_", 1L)); // full update
+    updates.add(simulatedDBQ("inplace_updatable_int:5", 3L));
+    updates.add(simulatedUpdateRequest(1L, "id", 1, "inplace_updatable_int", 6, "_version_", 2L));
+    for (JettySolrRunner solrRunner: getSolrRunner(false)) {
+      try (SolrClient client = solrRunner.newClient()) {
+        for (UpdateRequest up : updates) {
+          up.process(client, collectionName);
+        }
+      }
+    }
+    JettySolrRunner oldLeaderJetty = getSolrRunner(true).get(0);
+    ChaosMonkey.kill(oldLeaderJetty);
+    waitForState("Replica not removed", collectionName, activeReplicaCount(0, 1, 0));
+    ChaosMonkey.start(oldLeaderJetty);
+    waitForState("Replica not added", collectionName, activeReplicaCount(0, 2, 0));
+    checkRTG(1,1, cluster.getJettySolrRunners());
+    SolrDocument doc = cluster.getSolrClient().getById(collectionName,"1");
+    assertNotNull(doc.get("title_s"));
+  }
+  
+  private UpdateRequest simulatedUpdateRequest(Long prevVersion, Object... fields) throws SolrServerException, IOException {
+    SolrInputDocument doc = sdoc(fields);
+
+    // get baseUrl of the leader
+    String baseUrl = getBaseUrl();
+
+    UpdateRequest ur = new UpdateRequest();
+    ur.add(doc);
+    ur.setParam("update.distrib", "FROMLEADER");
+    if (prevVersion != null) {
+      ur.setParam("distrib.inplace.prevversion", String.valueOf(prevVersion));
+      ur.setParam("distrib.inplace.update", "true");
+    }
+    ur.setParam("distrib.from", baseUrl);
+    return ur;
+  }
+
+  private UpdateRequest simulatedDBQ(String query, long version) throws SolrServerException, IOException {
+    String baseUrl = getBaseUrl();
+
+    UpdateRequest ur = new UpdateRequest();
+    ur.deleteByQuery(query);
+    ur.setParam("_version_", ""+version);
+    ur.setParam("update.distrib", "FROMLEADER");
+    ur.setParam("distrib.from", baseUrl);
+    return ur;
+  }
+
+  private String getBaseUrl() {
+    DocCollection collection = cluster.getSolrClient().getZkStateReader().getClusterState().getCollection(collectionName);
+    Slice slice = collection.getSlice("shard1");
+    return slice.getLeader().getCoreUrl();
+  }
+
+  private DocCollection createAndWaitForCollection(int numShards, int numNrtReplicas, int numTlogReplicas, int numPullReplicas) throws SolrServerException, IOException, KeeperException, InterruptedException {
+    CollectionAdminRequest.createCollection(collectionName, "conf", numShards, numNrtReplicas, numTlogReplicas, numPullReplicas)
+    .setMaxShardsPerNode(100)
+    .process(cluster.getSolrClient());
+    int numReplicasPerShard = numNrtReplicas + numTlogReplicas + numPullReplicas;
+    cluster.getSolrClient().getZkStateReader().registerCore(collectionName); //TODO: Is this needed? 
+    waitForState("Expected collection to be created with " + numShards + " shards and  " + numReplicasPerShard + " replicas", 
+        collectionName, clusterShape(numShards, numReplicasPerShard));
+    return assertNumberOfReplicas(numNrtReplicas*numShards, numTlogReplicas*numShards, numPullReplicas*numShards, false, true);
+  }
+  
+  private void waitForNumDocsInAllActiveReplicas(int numDocs) throws IOException, SolrServerException, InterruptedException {
+    waitForNumDocsInAllActiveReplicas(numDocs, REPLICATION_TIMEOUT_SECS);
+  }
+  
+  private void waitForNumDocsInAllActiveReplicas(int numDocs, int timeout) throws IOException, SolrServerException, InterruptedException {
+    DocCollection docCollection = getCollectionState(collectionName);
+    waitForNumDocsInAllReplicas(numDocs, docCollection.getReplicas().stream().filter(r -> r.getState() == Replica.State.ACTIVE).collect(Collectors.toList()), timeout);
+  }
+    
+  private void waitForNumDocsInAllReplicas(int numDocs, Collection<Replica> replicas, int timeout) throws IOException, SolrServerException, InterruptedException {
+    waitForNumDocsInAllReplicas(numDocs, replicas, "*:*", timeout);
+  }
+  
+  private void waitForNumDocsInAllReplicas(int numDocs, Collection<Replica> replicas, String query, int timeout) throws IOException, SolrServerException, InterruptedException {
+    TimeOut t = new TimeOut(timeout, TimeUnit.SECONDS);
+    for (Replica r:replicas) {
+      if (!r.isActive(cluster.getSolrClient().getZkStateReader().getClusterState().getLiveNodes())) {
+        continue;
+      }
+      try (HttpSolrClient replicaClient = getHttpSolrClient(r.getCoreUrl())) {
+        while (true) {
+          try {
+            assertEquals("Replica " + r.getName() + " not up to date after " + REPLICATION_TIMEOUT_SECS + " seconds",
+                numDocs, replicaClient.query(new SolrQuery(query)).getResults().getNumFound());
+            break;
+          } catch (AssertionError e) {
+            if (t.hasTimedOut()) {
+              throw e;
+            } else {
+              Thread.sleep(100);
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  private void waitForDeletion(String collection) throws InterruptedException, KeeperException {
+    TimeOut t = new TimeOut(10, TimeUnit.SECONDS);
+    while (cluster.getSolrClient().getZkStateReader().getClusterState().hasCollection(collection)) {
+      try {
+        Thread.sleep(100);
+        if (t.hasTimedOut()) {
+          fail("Timed out waiting for collection " + collection + " to be deleted.");
+        }
+        cluster.getSolrClient().getZkStateReader().forceUpdateCollection(collection);
+      } catch(SolrException e) {
+        return;
+      }
+      
+    }
+  }
+  
+  private DocCollection assertNumberOfReplicas(int numNrtReplicas, int numTlogReplicas, int numPullReplicas, boolean updateCollection, boolean activeOnly) throws KeeperException, InterruptedException {
+    if (updateCollection) {
+      cluster.getSolrClient().getZkStateReader().forceUpdateCollection(collectionName);
+    }
+    DocCollection docCollection = getCollectionState(collectionName);
+    assertNotNull(docCollection);
+    assertEquals("Unexpected number of nrt replicas: " + docCollection, numNrtReplicas, 
+        docCollection.getReplicas(EnumSet.of(Replica.Type.NRT)).stream().filter(r->!activeOnly || r.getState() == Replica.State.ACTIVE).count());
+    assertEquals("Unexpected number of pull replicas: " + docCollection, numPullReplicas, 
+        docCollection.getReplicas(EnumSet.of(Replica.Type.PULL)).stream().filter(r->!activeOnly || r.getState() == Replica.State.ACTIVE).count());
+    assertEquals("Unexpected number of tlog replicas: " + docCollection, numTlogReplicas, 
+        docCollection.getReplicas(EnumSet.of(Replica.Type.TLOG)).stream().filter(r->!activeOnly || r.getState() == Replica.State.ACTIVE).count());
+    return docCollection;
+  }
+  
+  /*
+   * passes only if all replicas are active or down, and the "liveNodes" reflect the same status
+   */
+  private CollectionStatePredicate clusterStateReflectsActiveAndDownReplicas() {
+    return (liveNodes, collectionState) -> {
+      for (Replica r:collectionState.getReplicas()) {
+        if (r.getState() != Replica.State.DOWN && r.getState() != Replica.State.ACTIVE) {
+          return false;
+        }
+        if (r.getState() == Replica.State.DOWN && liveNodes.contains(r.getNodeName())) {
+          return false;
+        }
+        if (r.getState() == Replica.State.ACTIVE && !liveNodes.contains(r.getNodeName())) {
+          return false;
+        }
+      }
+      return true;
+    };
+  }
+  
+  
+  private CollectionStatePredicate activeReplicaCount(int numNrtReplicas, int numTlogReplicas, int numPullReplicas) {
+    return (liveNodes, collectionState) -> {
+      int nrtFound = 0, tlogFound = 0, pullFound = 0;
+      if (collectionState == null)
+        return false;
+      for (Slice slice : collectionState) {
+        for (Replica replica : slice) {
+          if (replica.isActive(liveNodes))
+            switch (replica.getType()) {
+              case TLOG:
+                tlogFound++;
+                break;
+              case PULL:
+                pullFound++;
+                break;
+              case NRT:
+                nrtFound++;
+                break;
+              default:
+                throw new AssertionError("Unexpected replica type");
+            }
+        }
+      }
+      return numNrtReplicas == nrtFound && numTlogReplicas == tlogFound && numPullReplicas == pullFound;
+    };
+  }
+  
+  private List<SolrCore> getSolrCore(boolean isLeader) {
+    List<SolrCore> rs = new ArrayList<>();
+
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    DocCollection docCollection = cloudClient.getZkStateReader().getClusterState().getCollection(collectionName);
+
+    for (JettySolrRunner solrRunner : cluster.getJettySolrRunners()) {
+      if (solrRunner.getCoreContainer() == null) continue;
+      for (SolrCore solrCore : solrRunner.getCoreContainer().getCores()) {
+        CloudDescriptor cloudDescriptor = solrCore.getCoreDescriptor().getCloudDescriptor();
+        Slice slice = docCollection.getSlice(cloudDescriptor.getShardId());
+        Replica replica = docCollection.getReplica(cloudDescriptor.getCoreNodeName());
+        if (slice.getLeader().equals(replica) && isLeader) {
+          rs.add(solrCore);
+        } else if (!slice.getLeader().equals(replica) && !isLeader) {
+          rs.add(solrCore);
+        }
+      }
+    }
+    return rs;
+  }
+  
+  private void checkRTG(int from, int to, List<JettySolrRunner> solrRunners) throws Exception{
+    for (JettySolrRunner solrRunner: solrRunners) {
+      try (SolrClient client = solrRunner.newClient()) {
+        for (int i = from; i <= to; i++) {
+          SolrQuery query = new SolrQuery();
+          query.set("distrib", false);
+          query.setRequestHandler("/get");
+          query.set("id",i);
+          QueryResponse res = client.query(collectionName, query);
+          assertNotNull("Can not find doc "+ i + " in " + solrRunner.getBaseUrl(),res.getResponse().get("doc"));
+        }
+      }
+    }
+  }
+  
+  private List<JettySolrRunner> getSolrRunner(boolean isLeader) {
+    List<JettySolrRunner> rs = new ArrayList<>();
+    CloudSolrClient cloudClient = cluster.getSolrClient();
+    DocCollection docCollection = cloudClient.getZkStateReader().getClusterState().getCollection(collectionName);
+    for (JettySolrRunner solrRunner : cluster.getJettySolrRunners()) {
+      if (solrRunner.getCoreContainer() == null) continue;
+      for (SolrCore solrCore : solrRunner.getCoreContainer().getCores()) {
+        CloudDescriptor cloudDescriptor = solrCore.getCoreDescriptor().getCloudDescriptor();
+        Slice slice = docCollection.getSlice(cloudDescriptor.getShardId());
+        Replica replica = docCollection.getReplica(cloudDescriptor.getCoreNodeName());
+        if (slice.getLeader() == replica && isLeader) {
+          rs.add(solrRunner);
+        } else if (slice.getLeader() != replica && !isLeader) {
+          rs.add(solrRunner);
+        }
+      }
+    }
+    return rs;
+  }
+  
+  private void waitForReplicasCatchUp(int numTry) throws IOException, InterruptedException {
+    String leaderTimeCommit = getSolrCore(true).get(0).getDeletionPolicy().getLatestCommit().getUserData().get(SolrIndexWriter.COMMIT_TIME_MSEC_KEY);
+    if (leaderTimeCommit == null) return;
+    for (int i = 0; i < numTry; i++) {
+      boolean inSync = true;
+      for (SolrCore solrCore : getSolrCore(false)) {
+        String replicateTimeCommit = solrCore.getDeletionPolicy().getLatestCommit().getUserData().get(SolrIndexWriter.COMMIT_TIME_MSEC_KEY);
+        if (!leaderTimeCommit.equals(replicateTimeCommit)) {
+          inSync = false;
+          Thread.sleep(500);
+          break;
+        }
+      }
+      if (inSync) return;
+    }
+
+    fail("Some replicas are not in sync with leader");
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
index f66f892..73a2851 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
@@ -86,10 +86,10 @@ public class TestTolerantUpdateProcessorCloud extends SolrCloudTestCase {
   /** A client for talking directly to the leader of shard2 */
   private static HttpSolrClient S_TWO_LEADER_CLIENT;
 
-  /** A client for talking directly to a passive replica of shard1 */
+  /** A client for talking directly to a pull replica of shard1 */
   private static HttpSolrClient S_ONE_NON_LEADER_CLIENT;
   
-  /** A client for talking directly to a passive replica of shard2 */
+  /** A client for talking directly to a pull replica of shard2 */
   private static HttpSolrClient S_TWO_NON_LEADER_CLIENT;
 
   /** A client for talking directly to a node that has no piece of the collection */

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsBasicDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsBasicDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsBasicDistributedZkTest.java
index ba92a02..1534162 100644
--- a/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsBasicDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsBasicDistributedZkTest.java
@@ -44,7 +44,7 @@ public class HdfsBasicDistributedZkTest extends BasicDistributedZkTest {
   }
 
   @Override
-  protected boolean useAppendReplicas() {
+  protected boolean useTlogReplicas() {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
index ebb758d..44b4a4e 100644
--- a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
+++ b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
@@ -111,7 +111,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
   }
 
   @Override
-  protected boolean useAppendReplicas() {
+  protected boolean useTlogReplicas() {
     return onlyLeaderIndexes;
   }
 
@@ -270,7 +270,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
 
   private void reorderedDBQIndividualReplicaTest() throws Exception {
     if (onlyLeaderIndexes) {
-      log.info("RTG with DBQs are not working in append replicas");
+      log.info("RTG with DBQs are not working in tlog replicas");
       return;
     }
     clearIndex();
@@ -743,7 +743,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
    */
   private void reorderedDBQsResurrectionTest() throws Exception {
     if (onlyLeaderIndexes) {
-      log.info("RTG with DBQs are not working in append replicas");
+      log.info("RTG with DBQs are not working in tlog replicas");
       return;
     }
     clearIndex();
@@ -1145,7 +1145,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
    */
   private void reorderedDBQsUsingUpdatedValueFromADroppedUpdate() throws Exception {
     if (onlyLeaderIndexes) {
-      log.info("RTG with DBQs are not working in append replicas");
+      log.info("RTG with DBQs are not working in tlog replicas");
       return;
     }
     clearIndex();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index 0f062f5..e9b3700 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -897,7 +897,7 @@ public class CloudSolrClient extends SolrClient {
       String url = zkProps.getCoreUrl();
       urls.add(url);
       if (!directUpdatesToLeadersOnly) {
-        for (Replica replica : slice.getReplicas(EnumSet.of(Replica.Type.APPEND, Replica.Type.REALTIME))) {
+        for (Replica replica : slice.getReplicas(EnumSet.of(Replica.Type.TLOG, Replica.Type.NRT))) {
           if (!replica.getNodeName().equals(leader.getNodeName()) &&
               !replica.getName().equals(leader.getName())) {
             ZkCoreNodeProps zkProps1 = new ZkCoreNodeProps(replica);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
index 10b5c69..d5a2af6 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
@@ -322,12 +322,12 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
    * @param collection the collection name
    * @param config     the collection config
    * @param numShards  the number of shards in the collection
-   * @param numRealtimeReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#REALTIME} replicas
-   * @param numAppendReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#APPEND} replicas
-   * @param numPassiveReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#PASSIVE} replicas
+   * @param numNrtReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#NRT} replicas
+   * @param numTlogReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#TLOG} replicas
+   * @param numPullReplicas the number of {@link org.apache.solr.common.cloud.Replica.Type#PULL} replicas
    */
-  public static Create createCollection(String collection, String config, int numShards, int numRealtimeReplicas, int numAppendReplicas, int numPassiveReplicas) {
-    return new Create(collection, config, numShards, numRealtimeReplicas, numAppendReplicas, numPassiveReplicas);
+  public static Create createCollection(String collection, String config, int numShards, int numNrtReplicas, int numTlogReplicas, int numPullReplicas) {
+    return new Create(collection, config, numShards, numNrtReplicas, numTlogReplicas, numPullReplicas);
   }
   
   /**
@@ -371,14 +371,14 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
    * @param collection  the collection name
    * @param config      the collection config
    * @param shards      a shard definition string
-   * @param numRealtimeReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#REALTIME}
-   * @param numAppendReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#APPEND}
-   * @param numPassiveReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#PASSIVE}
+   * @param numNrtReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#NRT}
+   * @param numTlogReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#TLOG}
+   * @param numPullReplicas the number of replicas of type {@link org.apache.solr.common.cloud.Replica.Type#PULL}
    */
-  public static Create createCollectionWithImplicitRouter(String collection, String config, String shards, int numRealtimeReplicas, int numAppendReplicas, int numPassiveReplicas) {
-    Create createRequest = new Create(collection, config, shards, numRealtimeReplicas);
-    createRequest.appendReplicas = numAppendReplicas;
-    createRequest.passiveReplicas = numPassiveReplicas;
+  public static Create createCollectionWithImplicitRouter(String collection, String config, String shards, int numNrtReplicas, int numTlogReplicas, int numPullReplicas) {
+    Create createRequest = new Create(collection, config, shards, numNrtReplicas);
+    createRequest.tlogReplicas = numTlogReplicas;
+    createRequest.pullReplicas = numPullReplicas;
     return createRequest;
   }
 
@@ -392,9 +392,9 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
     protected String routerField;
     protected Integer numShards;
     protected Integer maxShardsPerNode;
-    protected Integer realtimeReplicas;
-    protected Integer passiveReplicas;
-    protected Integer appendReplicas;
+    protected Integer nrtReplicas;
+    protected Integer pullReplicas;
+    protected Integer tlogReplicas;
 
     private Properties properties;
     protected Boolean autoAddReplicas;
@@ -409,19 +409,19 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
       super(CollectionAction.CREATE, null);
     }
     
-    private Create(String collection, String config, int numShards, int numRealtimeReplicas, int numAppendReplicas, int numPassiveReplicas) { // TODO: maybe add other constructors
+    private Create(String collection, String config, int numShards, int numNrtReplicas, int numTlogReplicas, int numPullReplicas) { // TODO: maybe add other constructors
       super(CollectionAction.CREATE, SolrIdentifierValidator.validateCollectionName(collection));
       this.configName = config;
       this.numShards = numShards;
-      this.realtimeReplicas = numRealtimeReplicas;
-      this.passiveReplicas = numPassiveReplicas;
-      this.appendReplicas = numAppendReplicas;
+      this.nrtReplicas = numNrtReplicas;
+      this.pullReplicas = numPullReplicas;
+      this.tlogReplicas = numTlogReplicas;
     }
 
-    private Create(String collection, String config, String shards, int numRealtimeReplicas) {
+    private Create(String collection, String config, String shards, int numNrtReplicas) {
       super(CollectionAction.CREATE, SolrIdentifierValidator.validateCollectionName(collection));
       this.configName = config;
-      this.realtimeReplicas = numRealtimeReplicas;
+      this.nrtReplicas = numNrtReplicas;
       this.shards = shards;
       this.routerName = ImplicitDocRouter.NAME;
     }
@@ -435,10 +435,10 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
     public Create setNumShards(Integer numShards) {this.numShards = numShards; return this; }
     public Create setMaxShardsPerNode(Integer numShards) { this.maxShardsPerNode = numShards; return this; }
     public Create setAutoAddReplicas(boolean autoAddReplicas) { this.autoAddReplicas = autoAddReplicas; return this; }
-    public Create setRealtimeReplicas(Integer realtimeReplicas) { this.realtimeReplicas = realtimeReplicas; return this;}
-    public Create setAppendReplicas(Integer appendReplicas) { this.appendReplicas = appendReplicas; return this;}
+    public Create setNrtReplicas(Integer nrtReplicas) { this.nrtReplicas = nrtReplicas; return this;}
+    public Create setTlogReplicas(Integer tlogReplicas) { this.tlogReplicas = tlogReplicas; return this;}
 
-    public Create setReplicationFactor(Integer repl) { this.realtimeReplicas = repl; return this; }
+    public Create setReplicationFactor(Integer repl) { this.nrtReplicas = repl; return this; }
     public Create setStateFormat(Integer stateFormat) { this.stateFormat = stateFormat; return this; }
     public Create setRule(String... s){ this.rule = s; return this; }
     public Create setSnitch(String... s){ this.snitch = s; return this; }
@@ -450,11 +450,11 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
     public Integer getNumShards() { return numShards; }
     public Integer getMaxShardsPerNode() { return maxShardsPerNode; }
     
-    public Integer getReplicationFactor() { return getNumRealtimeReplicas(); }
-    public Integer getNumRealtimeReplicas() { return realtimeReplicas; }
+    public Integer getReplicationFactor() { return getNumNrtReplicas(); }
+    public Integer getNumNrtReplicas() { return nrtReplicas; }
     public Boolean getAutoAddReplicas() { return autoAddReplicas; }
-    public Integer getRealtimeReplicas() { return realtimeReplicas; }
-    public Integer getAppendReplicas() {return appendReplicas;}
+    public Integer getNrtReplicas() { return nrtReplicas; }
+    public Integer getTlogReplicas() {return tlogReplicas;}
 
     public Integer getStateFormat() { return stateFormat; }
     
@@ -536,9 +536,9 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
       if (routerField != null) {
         params.set("router.field", routerField);
       }
-      if (realtimeReplicas != null) {
-        params.set( "replicationFactor", realtimeReplicas);// Keep both for compatibility?
-        params.set( ZkStateReader.REALTIME_REPLICAS, realtimeReplicas);
+      if (nrtReplicas != null) {
+        params.set( "replicationFactor", nrtReplicas);// Keep both for compatibility?
+        params.set( ZkStateReader.NRT_REPLICAS, nrtReplicas);
       }
       if (autoAddReplicas != null) {
         params.set(ZkStateReader.AUTO_ADD_REPLICAS, autoAddReplicas);
@@ -549,11 +549,11 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
       if (stateFormat != null) {
         params.set(DocCollection.STATE_FORMAT, stateFormat);
       }
-      if (passiveReplicas != null) {
-        params.set(ZkStateReader.PASSIVE_REPLICAS, passiveReplicas);
+      if (pullReplicas != null) {
+        params.set(ZkStateReader.PULL_REPLICAS, pullReplicas);
       }
-      if (appendReplicas != null) {
-        params.set(ZkStateReader.APPEND_REPLICAS, appendReplicas);
+      if (tlogReplicas != null) {
+        params.set(ZkStateReader.TLOG_REPLICAS, tlogReplicas);
       }
       if(rule != null) params.set("rule", rule);
       if(snitch != null) params.set("snitch", snitch);
@@ -1656,7 +1656,7 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
    * Returns a SolrRequest to add a replica to a shard in a collection
    */
   public static AddReplica addReplicaToShard(String collection, String shard) {
-    return addReplicaToShard(collection, shard, Replica.Type.REALTIME);
+    return addReplicaToShard(collection, shard, Replica.Type.NRT);
   }
 
   /**
@@ -1670,7 +1670,7 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
    * Returns a SolrRequest to add a replica to a collection using a route key
    */
   public static AddReplica addReplicaByRouteKey(String collection, String routeKey) {
-    return new AddReplica(collection, null, routeKey, Replica.Type.REALTIME);
+    return new AddReplica(collection, null, routeKey, Replica.Type.NRT);
   }
 
   // ADDREPLICA request

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
index 3b6ac80..47bdce3 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
@@ -35,9 +35,9 @@ import org.noggit.JSONWriter;
 import static org.apache.solr.common.cloud.ZkStateReader.AUTO_ADD_REPLICAS;
 import static org.apache.solr.common.cloud.ZkStateReader.MAX_SHARDS_PER_NODE;
 import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
-import static org.apache.solr.common.cloud.ZkStateReader.REALTIME_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.APPEND_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.PASSIVE_REPLICAS;
+import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
+import static org.apache.solr.common.cloud.ZkStateReader.TLOG_REPLICAS;
+import static org.apache.solr.common.cloud.ZkStateReader.PULL_REPLICAS;
 
 /**
  * Models a Collection in zookeeper (but that Java name is obviously taken, hence "DocCollection")
@@ -61,9 +61,9 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
   private final String znode;
 
   private final Integer replicationFactor;
-  private final Integer numRealtimeReplicas;
-  private final Integer numAppendReplicas;
-  private final Integer numPassiveReplicas;
+  private final Integer numNrtReplicas;
+  private final Integer numTlogReplicas;
+  private final Integer numPullReplicas;
   private final Integer maxShardsPerNode;
   private final Boolean autoAddReplicas;
 
@@ -87,9 +87,9 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
     this.nodeNameLeaderReplicas = new HashMap<>();
     this.nodeNameReplicas = new HashMap<>();
     this.replicationFactor = (Integer) verifyProp(props, REPLICATION_FACTOR);
-    this.numRealtimeReplicas = (Integer) verifyProp(props, REALTIME_REPLICAS);
-    this.numAppendReplicas = (Integer) verifyProp(props, APPEND_REPLICAS);
-    this.numPassiveReplicas = (Integer) verifyProp(props, PASSIVE_REPLICAS);
+    this.numNrtReplicas = (Integer) verifyProp(props, NRT_REPLICAS);
+    this.numTlogReplicas = (Integer) verifyProp(props, TLOG_REPLICAS);
+    this.numPullReplicas = (Integer) verifyProp(props, PULL_REPLICAS);
     this.maxShardsPerNode = (Integer) verifyProp(props, MAX_SHARDS_PER_NODE);
     Boolean autoAddReplicas = (Boolean) verifyProp(props, AUTO_ADD_REPLICAS);
     this.autoAddReplicas = autoAddReplicas == null ? Boolean.FALSE : autoAddReplicas;
@@ -136,9 +136,9 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
     switch (propName) {
       case MAX_SHARDS_PER_NODE:
       case REPLICATION_FACTOR:
-      case REALTIME_REPLICAS:
-      case PASSIVE_REPLICAS:
-      case APPEND_REPLICAS:
+      case NRT_REPLICAS:
+      case PULL_REPLICAS:
+      case TLOG_REPLICAS:
         return Integer.parseInt(o.toString());
       case AUTO_ADD_REPLICAS:
         return Boolean.parseBoolean(o.toString());
@@ -342,16 +342,16 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
     return super.equals(that) && Objects.equals(this.znode, other.znode) && this.znodeVersion == other.znodeVersion;
   }
 
-  public Integer getNumRealtimeReplicas() {
-    return numRealtimeReplicas;
+  public Integer getNumNrtReplicas() {
+    return numNrtReplicas;
   }
 
-  public Integer getNumAppendReplicas() {
-    return numAppendReplicas;
+  public Integer getNumTlogReplicas() {
+    return numTlogReplicas;
   }
 
-  public Integer getNumPassiveReplicas() {
-    return numPassiveReplicas;
+  public Integer getNumPullReplicas() {
+    return numPullReplicas;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
index 8f3ed15..b7655be 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
@@ -86,23 +86,23 @@ public class Replica extends ZkNodeProps {
 
   public enum Type {
     /**
-     * Writes updates to transaction log and indexes locally. Replicas of type {@link #REALTIME} support NRT (soft commits) and RTG. 
-     * Any {@link #REALTIME} replica can become a leader. A shard leader will forward updates to all active {@link #REALTIME} and
-     * {@link #APPEND} replicas. 
+     * Writes updates to transaction log and indexes locally. Replicas of type {@link Type#NRT} support NRT (soft commits) and RTG. 
+     * Any {@link Type#NRT} replica can become a leader. A shard leader will forward updates to all active {@link Type#NRT} and
+     * {@link Type#TLOG} replicas. 
      */
-    REALTIME,
+    NRT,
     /**
-     * Writes to transaction log, but not to index, uses replication. Any {@link #APPEND} replica can become leader (by first
-     * applying all local transaction log elements). If a replica is of type {@link #APPEND} but is also the leader, it will behave 
-     * as a {@link #REALTIME}. A shard leader will forward updates to all active {@link #REALTIME} and {@link #APPEND} replicas.
+     * Writes to transaction log, but not to index, uses replication. Any {@link Type#TLOG} replica can become leader (by first
+     * applying all local transaction log elements). If a replica is of type {@link Type#TLOG} but is also the leader, it will behave 
+     * as a {@link Type#NRT}. A shard leader will forward updates to all active {@link Type#NRT} and {@link Type#TLOG} replicas.
      */
-    APPEND,
+    TLOG,
     /**
-     * Doesn’t index or writes to transaction log. Just replicates from {@link #REALTIME} or {@link #APPEND} replicas. {@link #PASSIVE}
-     * replicas can’t become shard leaders (i.e., if there are only passive replicas in the collection at some point, updates will fail
+     * Doesn’t index or writes to transaction log. Just replicates from {@link Type#NRT} or {@link Type#TLOG} replicas. {@link Type#PULL}
+     * replicas can’t become shard leaders (i.e., if there are only pull replicas in the collection at some point, updates will fail
      * same as if there is no leaders, queries continue to work), so they don’t even participate in elections.
      */
-    PASSIVE
+    PULL
   }
 
   private final String name;
@@ -122,7 +122,7 @@ public class Replica extends ZkNodeProps {
     }
     String typeString = (String)propMap.get(ZkStateReader.REPLICA_TYPE);
     if (typeString == null) {
-      this.type = Type.REALTIME;
+      this.type = Type.NRT;
     } else {
       this.type = Type.valueOf(typeString);
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
index 3f84e1e..844714d 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
@@ -205,7 +205,7 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
   private Replica findLeader() {
     for (Replica replica : replicas.values()) {
       if (replica.getStr(LEADER) != null) {
-        assert replica.getType() == Type.APPEND || replica.getType() == Type.REALTIME: "Passive replica should not become leader!";
+        assert replica.getType() == Type.TLOG || replica.getType() == Type.NRT: "Pull replica should not become leader!";
         return replica;
       }
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index 3f6f1ac..3c3497a 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -99,9 +99,9 @@ public class ZkStateReader implements Closeable {
   public static final String AUTO_ADD_REPLICAS = "autoAddReplicas";
   public static final String MAX_CORES_PER_NODE = "maxCoresPerNode";
   //TODO: Move these constants out of ZkStateReader
-  public static final String PASSIVE_REPLICAS = "passiveReplicas";
-  public static final String REALTIME_REPLICAS = "realtimeReplicas";
-  public static final String APPEND_REPLICAS = "appendReplicas";
+  public static final String PULL_REPLICAS = "pullReplicas";
+  public static final String NRT_REPLICAS = "nrtReplicas";
+  public static final String TLOG_REPLICAS = "tlogReplicas";
 
   public static final String ROLES = "/roles.json";
 
@@ -788,7 +788,7 @@ public class ZkStateReader implements Closeable {
   public List<ZkCoreNodeProps> getReplicaProps(String collection, String shardId, String thisCoreNodeName,
       Replica.State mustMatchStateFilter, Replica.State mustNotMatchStateFilter) {
     //nocommit: We don't need all these getReplicaProps method overloading. Also, it's odd that the default is to return replicas of type APPEND and REALTIME only
-    return getReplicaProps(collection, shardId, thisCoreNodeName, mustMatchStateFilter, null, EnumSet.of(Replica.Type.APPEND,  Replica.Type.REALTIME));
+    return getReplicaProps(collection, shardId, thisCoreNodeName, mustMatchStateFilter, null, EnumSet.of(Replica.Type.TLOG,  Replica.Type.NRT));
   }
   
   public List<ZkCoreNodeProps> getReplicaProps(String collection, String shardId, String thisCoreNodeName,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/solrj/src/test/org/apache/solr/client/solrj/CollectionAdminRequestRequiredParamsTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/CollectionAdminRequestRequiredParamsTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/CollectionAdminRequestRequiredParamsTest.java
index 7a89dec..0f9b147 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/CollectionAdminRequestRequiredParamsTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/CollectionAdminRequestRequiredParamsTest.java
@@ -81,7 +81,7 @@ public class CollectionAdminRequestRequiredParamsTest extends LuceneTestCase {
     request = new CollectionAdminRequest.AddReplica()
             .setShardName("shard")
             .setCollectionName("collection")
-            .setType(Replica.Type.REALTIME);
+            .setType(Replica.Type.NRT);
     assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, ZkStateReader.REPLICA_TYPE);
   }
   

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
index 2d082ea..f30c035 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
@@ -236,10 +236,10 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
             CreateMode.PERSISTENT, true);
       }
     }
-    if (useAppendReplicas()) {
-      log.info("Will use {} replicas unless explicitly asked otherwise", Replica.Type.APPEND);
+    if (useTlogReplicas()) {
+      log.info("Will use {} replicas unless explicitly asked otherwise", Replica.Type.TLOG);
     } else {
-      log.info("Will use {} replicas unless explicitly asked otherwise", Replica.Type.REALTIME);
+      log.info("Will use {} replicas unless explicitly asked otherwise", Replica.Type.NRT);
     }
   }
 
@@ -281,7 +281,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
         shardToJetty, shardToLeaderJetty);
   }
 
-  protected boolean useAppendReplicas() {
+  protected boolean useTlogReplicas() {
     return false;
   }
   
@@ -397,13 +397,13 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
               "name", DEFAULT_COLLECTION, 
               "numShards", String.valueOf(sliceCount),
               DocCollection.STATE_FORMAT, getStateFormat(),
-              ZkStateReader.REALTIME_REPLICAS, useAppendReplicas()?"0":"1",
-              ZkStateReader.APPEND_REPLICAS, useAppendReplicas()?"1":"0",
-              ZkStateReader.PASSIVE_REPLICAS, String.valueOf(getPassiveReplicaCount()))));
+              ZkStateReader.NRT_REPLICAS, useTlogReplicas()?"0":"1",
+              ZkStateReader.TLOG_REPLICAS, useTlogReplicas()?"1":"0",
+              ZkStateReader.PULL_REPLICAS, String.valueOf(getPullReplicaCount()))));
       zkClient.close();
     }
     
-    int numPassiveReplicas = getPassiveReplicaCount() * sliceCount;
+    int numPullReplicas = getPullReplicaCount() * sliceCount;
 
     for (int i = 1; i <= numJettys; i++) {
       if (sb.length() > 0) sb.append(',');
@@ -415,17 +415,17 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
       setupJettySolrHome(jettyDir);
       JettySolrRunner j;
       
-      if (numPassiveReplicas > 0) {
-        numPassiveReplicas--;
-        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.PASSIVE);
+      if (numPullReplicas > 0) {
+        numPullReplicas--;
+        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.PULL);
         j = createJetty(jettyDir, useJettyDataDir ? getDataDir(testDir + "/jetty"
-            + cnt) : null, null, "solrconfig.xml", null, Replica.Type.PASSIVE);
-      } else if (useAppendReplicas()) {
-        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.APPEND);
+            + cnt) : null, null, "solrconfig.xml", null, Replica.Type.PULL);
+      } else if (useTlogReplicas()) {
+        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.TLOG);
         j = createJetty(jettyDir, useJettyDataDir ? getDataDir(testDir + "/jetty"
-            + cnt) : null, null, "solrconfig.xml", null, Replica.Type.APPEND);
+            + cnt) : null, null, "solrconfig.xml", null, Replica.Type.TLOG);
       } else {
-        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.REALTIME);
+        log.info("create jetty {} in directory {} of type {}", i, jettyDir, Replica.Type.NRT);
         j = createJetty(jettyDir, useJettyDataDir ? getDataDir(testDir + "/jetty"
             + cnt) : null, null, "solrconfig.xml", null, null);
       }
@@ -477,7 +477,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
   }
 
 
-  protected int getPassiveReplicaCount() {
+  protected int getPullReplicaCount() {
     return 0;
   }
 
@@ -547,7 +547,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
     if (replicaType != null) {
       props.setProperty("replicaType", replicaType.toString());
     } else if (random().nextBoolean()) {
-      props.setProperty("replicaType", Replica.Type.REALTIME.toString());
+      props.setProperty("replicaType", Replica.Type.NRT.toString());
     }
     props.setProperty("coreRootDirectory", solrHome.toPath().resolve("cores").toAbsolutePath().toString());
     
@@ -586,7 +586,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
     if (replicaType != null) {
       props.setProperty("replicaType", replicaType.toString());
     } else if (random().nextBoolean()) {
-      props.setProperty("replicaType", Replica.Type.REALTIME.toString());
+      props.setProperty("replicaType", Replica.Type.NRT.toString());
     }
     props.setProperty("coreRootDirectory", solrHome.toPath().resolve("cores").toAbsolutePath().toString());
 
@@ -1616,23 +1616,23 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
       String shardNames = (String) collectionProps.get(SHARDS_PROP);
       numShards = StrUtils.splitSmart(shardNames,',').size();
     }
-    Integer numRealtimeReplicas = (Integer) collectionProps.get(ZkStateReader.REALTIME_REPLICAS);
-    if (numRealtimeReplicas == null) {
-      numRealtimeReplicas = (Integer) collectionProps.get(ZkStateReader.REPLICATION_FACTOR);
+    Integer numNrtReplicas = (Integer) collectionProps.get(ZkStateReader.NRT_REPLICAS);
+    if (numNrtReplicas == null) {
+      numNrtReplicas = (Integer) collectionProps.get(ZkStateReader.REPLICATION_FACTOR);
     }
-    if(numRealtimeReplicas == null){
-      numRealtimeReplicas = (Integer) OverseerCollectionMessageHandler.COLL_PROPS.get(ZkStateReader.REPLICATION_FACTOR);
+    if(numNrtReplicas == null){
+      numNrtReplicas = (Integer) OverseerCollectionMessageHandler.COLL_PROPS.get(ZkStateReader.REPLICATION_FACTOR);
     }
-    if (numRealtimeReplicas == null) {
-      numRealtimeReplicas = Integer.valueOf(0);
+    if (numNrtReplicas == null) {
+      numNrtReplicas = Integer.valueOf(0);
     }
-    Integer numAppendReplicas = (Integer) collectionProps.get(ZkStateReader.APPEND_REPLICAS);
-    if (numAppendReplicas == null) {
-      numAppendReplicas = Integer.valueOf(0);
+    Integer numTlogReplicas = (Integer) collectionProps.get(ZkStateReader.TLOG_REPLICAS);
+    if (numTlogReplicas == null) {
+      numTlogReplicas = Integer.valueOf(0);
     }
-    Integer numPassiveReplicas = (Integer) collectionProps.get(ZkStateReader.PASSIVE_REPLICAS);
-    if (numPassiveReplicas == null) {
-      numPassiveReplicas = Integer.valueOf(0);
+    Integer numPullReplicas = (Integer) collectionProps.get(ZkStateReader.PULL_REPLICAS);
+    if (numPullReplicas == null) {
+      numPullReplicas = Integer.valueOf(0);
     }
     if (confSetName != null) {
       params.set("collection.configName", confSetName);
@@ -1641,7 +1641,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
     int clientIndex = random().nextInt(2);
     List<Integer> list = new ArrayList<>();
     list.add(numShards);
-    list.add(numRealtimeReplicas + numAppendReplicas + numPassiveReplicas);
+    list.add(numNrtReplicas + numTlogReplicas + numPullReplicas);
     if (collectionInfos != null) {
       collectionInfos.put(collectionName, list);
     }
@@ -1669,14 +1669,14 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
   protected CollectionAdminResponse createCollection(Map<String,List<Integer>> collectionInfos,
       String collectionName, int numShards, int replicationFactor, int maxShardsPerNode, SolrClient client, String createNodeSetStr) throws SolrServerException, IOException {
 
-    int numRealtimeReplicas = useAppendReplicas()?0:replicationFactor;
-    int numAppendReplicas = useAppendReplicas()?replicationFactor:0;
+    int numNrtReplicas = useTlogReplicas()?0:replicationFactor;
+    int numTlogReplicas = useTlogReplicas()?replicationFactor:0;
     return createCollection(collectionInfos, collectionName,
         Utils.makeMap(
         NUM_SLICES, numShards,
-        ZkStateReader.REALTIME_REPLICAS, numRealtimeReplicas,
-        ZkStateReader.APPEND_REPLICAS, numAppendReplicas,
-        ZkStateReader.PASSIVE_REPLICAS, getPassiveReplicaCount(),
+        ZkStateReader.NRT_REPLICAS, numNrtReplicas,
+        ZkStateReader.TLOG_REPLICAS, numTlogReplicas,
+        ZkStateReader.PULL_REPLICAS, getPullReplicaCount(),
         CREATE_NODE_SET, createNodeSetStr,
         ZkStateReader.MAX_SHARDS_PER_NODE, maxShardsPerNode),
         client);
@@ -1685,14 +1685,14 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
   protected CollectionAdminResponse createCollection(Map<String, List<Integer>> collectionInfos,
                                                      String collectionName, int numShards, int replicationFactor, int maxShardsPerNode, SolrClient client, String createNodeSetStr, String configName) throws SolrServerException, IOException {
 
-    int numRealtimeReplicas = useAppendReplicas()?0:replicationFactor;
-    int numAppendReplicas = useAppendReplicas()?replicationFactor:0;
+    int numNrtReplicas = useTlogReplicas()?0:replicationFactor;
+    int numTlogReplicas = useTlogReplicas()?replicationFactor:0;
     return createCollection(collectionInfos, collectionName,
         Utils.makeMap(
         NUM_SLICES, numShards,
-        ZkStateReader.REALTIME_REPLICAS, numRealtimeReplicas,
-        ZkStateReader.APPEND_REPLICAS, numAppendReplicas,
-        ZkStateReader.PASSIVE_REPLICAS, getPassiveReplicaCount(),
+        ZkStateReader.NRT_REPLICAS, numNrtReplicas,
+        ZkStateReader.TLOG_REPLICAS, numTlogReplicas,
+        ZkStateReader.PULL_REPLICAS, getPullReplicaCount(),
         CREATE_NODE_SET, createNodeSetStr,
         ZkStateReader.MAX_SHARDS_PER_NODE, maxShardsPerNode),
         client, configName);
@@ -1873,13 +1873,13 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
                                   int numShards ) throws Exception {
     int maxShardsPerNode = ((((numShards+1) * replicationFactor) / getCommonCloudSolrClient()
         .getZkStateReader().getClusterState().getLiveNodes().size())) + 1;
-    int numRealtimeReplicas = useAppendReplicas()?0:replicationFactor;
-    int numAppendReplicas = useAppendReplicas()?replicationFactor:0;
+    int numNrtReplicas = useTlogReplicas()?0:replicationFactor;
+    int numTlogReplicas = useTlogReplicas()?replicationFactor:0;
     Map<String, Object> props = makeMap(
         ZkStateReader.MAX_SHARDS_PER_NODE, maxShardsPerNode,
-        ZkStateReader.REALTIME_REPLICAS, numRealtimeReplicas,
-        ZkStateReader.APPEND_REPLICAS, numAppendReplicas,
-        ZkStateReader.PASSIVE_REPLICAS, getPassiveReplicaCount(),
+        ZkStateReader.NRT_REPLICAS, numNrtReplicas,
+        ZkStateReader.TLOG_REPLICAS, numTlogReplicas,
+        ZkStateReader.PULL_REPLICAS, getPullReplicaCount(),
         NUM_SLICES, numShards);
     Map<String,List<Integer>> collectionInfos = new HashMap<>();
     createCollection(collectionInfos, collName, props, client);
@@ -2078,24 +2078,24 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
       if (timeout.hasTimedOut()) {
         fail("Unable to get leader indexVersion");
       }
-      for (Replica passiveReplica:s.getReplicas(EnumSet.of(Replica.Type.PASSIVE,Replica.Type.APPEND))) {
-        if (!zkStateReader.getClusterState().liveNodesContain(passiveReplica.getNodeName())) {
+      for (Replica pullReplica:s.getReplicas(EnumSet.of(Replica.Type.PULL,Replica.Type.TLOG))) {
+        if (!zkStateReader.getClusterState().liveNodesContain(pullReplica.getNodeName())) {
           continue;
         }
         while (true) {
-          long replicaIndexVersion = getIndexVersion(passiveReplica); 
+          long replicaIndexVersion = getIndexVersion(pullReplica); 
           if (leaderIndexVersion == replicaIndexVersion) {
-            log.debug("Leader replica's version ({}) in sync with replica({}): {} == {}", leader.getName(), passiveReplica.getName(), leaderIndexVersion, replicaIndexVersion);
+            log.debug("Leader replica's version ({}) in sync with replica({}): {} == {}", leader.getName(), pullReplica.getName(), leaderIndexVersion, replicaIndexVersion);
             break;
           } else {
             if (timeout.hasTimedOut()) {
               logReplicaTypesReplicationInfo(collectionName, zkStateReader);
-              fail(String.format(Locale.ROOT, "Timed out waiting for replica %s (%d) to replicate from leader %s (%d)", passiveReplica.getName(), replicaIndexVersion, leader.getName(), leaderIndexVersion));
+              fail(String.format(Locale.ROOT, "Timed out waiting for replica %s (%d) to replicate from leader %s (%d)", pullReplica.getName(), replicaIndexVersion, leader.getName(), leaderIndexVersion));
             }
             if (leaderIndexVersion > replicaIndexVersion) {
-              log.debug("{} version is {} and leader's is {}, will wait for replication", passiveReplica.getName(), replicaIndexVersion, leaderIndexVersion);
+              log.debug("{} version is {} and leader's is {}, will wait for replication", pullReplica.getName(), replicaIndexVersion, leaderIndexVersion);
             } else {
-              log.debug("Leader replica's version ({}) is lower than passive replica({}): {} < {}", leader.getName(), passiveReplica.getName(), leaderIndexVersion, replicaIndexVersion);
+              log.debug("Leader replica's version ({}) is lower than pull replica({}): {} < {}", leader.getName(), pullReplica.getName(), leaderIndexVersion, replicaIndexVersion);
             }
             Thread.sleep(1000);
           }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9e82fd45/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
index 355e601..bdbbdd2 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
@@ -379,7 +379,7 @@ public class ChaosMonkey {
     boolean canKillIndexer = canKillIndexer(slice);
     
     if (!canKillIndexer) {
-      monkeyLog("Number of indexer nodes (realtime or append) is not enough to kill one of them, Will only choose a passive replica to kill");
+      monkeyLog("Number of indexer nodes (nrt or tlog replicas) is not enough to kill one of them, Will only choose a pull replica to kill");
     }
     
     int chance = chaosRandom.nextInt(10);
@@ -395,10 +395,10 @@ public class ChaosMonkey {
         attempt++;
         int index = chaosRandom.nextInt(jetties.size());
         cjetty = jetties.get(index);
-        if (canKillIndexer || getTypeForJetty(slice, cjetty) == Replica.Type.PASSIVE) {
+        if (canKillIndexer || getTypeForJetty(slice, cjetty) == Replica.Type.PULL) {
           break;
         } else if (attempt > 20) {
-          monkeyLog("Can't kill indexer nodes (realtime or append) and couldn't find a random passive node after 20 attempts - monkey cannot kill :(");
+          monkeyLog("Can't kill indexer nodes (nrt or tlog replicas) and couldn't find a random pull node after 20 attempts - monkey cannot kill :(");
           return null;
         }
       }
@@ -481,7 +481,7 @@ public class ChaosMonkey {
       
       if (cloudJetty.jetty.isRunning()
           && state == Replica.State.ACTIVE
-          && (replicaType == Replica.Type.APPEND || replicaType == Replica.Type.REALTIME) 
+          && (replicaType == Replica.Type.TLOG || replicaType == Replica.Type.NRT) 
           && zkStateReader.getClusterState().liveNodesContain(nodeName)) {
         numIndexersFoundInShard++;
       }