You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by an...@apache.org on 2014/12/30 00:37:04 UTC

svn commit: r1648446 - in /lucene/dev/trunk/solr: ./ core/src/test/org/apache/solr/cloud/ solrj/src/java/org/apache/solr/client/solrj/request/

Author: anshum
Date: Mon Dec 29 23:37:04 2014
New Revision: 1648446

URL: http://svn.apache.org/r1648446
Log:
SOLR-6448: SolrJ support for all Collection API calls

Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ReplicaPropertiesBase.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Mon Dec 29 23:37:04 2014
@@ -574,6 +574,8 @@ Other Changes
 * SOLR-6896: Speed up tests by dropping SolrJettyRunner thread max idle time
   (Alan Woodward)
 
+* SOLR-6448: Add SolrJ support for all current Collection API calls. (Anshum Gupta)
+
 ==================  4.10.3 ==================
 
 Bug Fixes

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java Mon Dec 29 23:37:04 2014
@@ -268,7 +268,7 @@ public class AliasIntegrationTest extend
       server.request(request);
     } else {
       CreateAlias request = new CreateAlias();
-      request.setCollectionName(alias);
+      request.setAliasName(alias);
       request.setAliasedCollections(collections);
       request.process(server);
     }
@@ -288,7 +288,7 @@ public class AliasIntegrationTest extend
       server.request(request);
     } else {
       DeleteAlias request = new DeleteAlias();
-      request.setCollectionName(alias);
+      request.setAliasName(alias);
       request.process(server);
     }
     server.shutdown();

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java Mon Dec 29 23:37:04 2014
@@ -25,7 +25,6 @@ import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -203,7 +202,6 @@ public class CollectionsAPIDistributedZk
     deletePartiallyCreatedCollection();
     deleteCollectionRemovesStaleZkCollectionsNode();
     clusterPropTest();
-    addReplicaTest();
     // last
     deleteCollectionWithDownNodes();
 
@@ -212,8 +210,6 @@ public class CollectionsAPIDistributedZk
     }
   }
 
-
-
   private void deleteCollectionRemovesStaleZkCollectionsNode() throws Exception {
     
     // we can use this client because we just want base url
@@ -1126,60 +1122,6 @@ public class CollectionsAPIDistributedZk
 
   }
 
-  private void addReplicaTest() throws Exception {
-    String collectionName = "addReplicaColl";
-    CloudSolrServer client = createCloudClient(null);
-    try {
-      createCollection(collectionName, client, 2, 2);
-      String newReplicaName = Assign.assignNode(collectionName, client.getZkStateReader().getClusterState());
-      ArrayList<String> nodeList = new ArrayList<>(client.getZkStateReader().getClusterState().getLiveNodes());
-      Collections.shuffle(nodeList, random());
-      CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica();
-      addReplica.setCollectionName(collectionName);
-      addReplica.setShardName("shard1");
-      addReplica.setNode(nodeList.get(0));
-      client.request(addReplica);
-
-      long timeout = System.currentTimeMillis() + 3000;
-      Replica newReplica = null;
-
-      for (; System.currentTimeMillis() < timeout; ) {
-        Slice slice = client.getZkStateReader().getClusterState().getSlice(collectionName, "shard1");
-        newReplica = slice.getReplica(newReplicaName);
-      }
-
-      assertNotNull(newReplica);
-
-      log.info("newReplica {},\n{} ", newReplica, client.getZkStateReader().getBaseUrlForNodeName(nodeList.get(0)));
-
-      assertEquals("Replica should be created on the right node",
-          client.getZkStateReader().getBaseUrlForNodeName(nodeList.get(0)), newReplica.getStr(ZkStateReader.BASE_URL_PROP));
-
-      newReplicaName = Assign.assignNode(collectionName, client.getZkStateReader().getClusterState());
-      addReplica = new CollectionAdminRequest.AddReplica();
-      addReplica.setCollectionName(collectionName);
-      addReplica.setShardName("shard2");
-      client.request(addReplica);
-
-      timeout = System.currentTimeMillis() + 3000;
-      newReplica = null;
-
-      for (; System.currentTimeMillis() < timeout; ) {
-        Slice slice = client.getZkStateReader().getClusterState().getSlice(collectionName, "shard2");
-        newReplica = slice.getReplica(newReplicaName);
-      }
-
-      assertNotNull(newReplica);
-
-
-    } finally {
-      client.shutdown();
-    }
-
-  }
-
-
-
   @Override
   protected QueryResponse queryServer(ModifiableSolrParams params) throws SolrServerException {
 
@@ -1236,9 +1178,9 @@ public class CollectionsAPIDistributedZk
     request.setPath("/admin/collections");
     client.request(request);
 
-    long tomeOut = System.currentTimeMillis() + 3000;
+    long timeOut = System.currentTimeMillis() + 3000;
     boolean changed = false;
-    while(System.currentTimeMillis() <tomeOut){
+    while(System.currentTimeMillis() <timeOut){
       Thread.sleep(10);
       changed = Objects.equals(val,client.getZkStateReader().getClusterProps().get(name));
       if(changed) break;

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java Mon Dec 29 23:37:04 2014
@@ -17,6 +17,7 @@ package org.apache.solr.cloud;
  * limitations under the License.
  */
 
+import org.apache.commons.codec.binary.StringUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 import org.apache.solr.client.solrj.SolrServerException;
@@ -32,13 +33,20 @@ import org.apache.solr.common.cloud.Slic
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.CoreAdminParams;
 import org.apache.solr.common.util.NamedList;
+import org.apache.zookeeper.KeeperException;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Properties;
 
+import static org.apache.solr.cloud.ReplicaPropertiesBase.verifyUniqueAcrossCollection;
+
 @LuceneTestCase.Slow
 public class CollectionsAPISolrJTests extends AbstractFullDistribZkTestBase {
   
@@ -50,6 +58,13 @@ public class CollectionsAPISolrJTests ex
     testCreateAndDeleteAlias();
     testSplitShard();
     testCreateCollectionWithPropertyParam();
+    testAddAndDeleteReplica();
+    testClusterProp();
+    testAddAndRemoveRole();
+    testOverseerStatus();
+    testList();
+    testAddAndDeleteReplicaProp();
+    testBalanceShardUnique();
   }
 
   public void tearDown() throws Exception {
@@ -65,7 +80,6 @@ public class CollectionsAPISolrJTests ex
     super.tearDown();
   }
 
-
   protected void testCreateAndDeleteCollection() throws Exception {
     String collectionName = "solrj_test";
     CollectionAdminRequest.Create createCollectionRequest = new CollectionAdminRequest.Create();
@@ -170,14 +184,14 @@ public class CollectionsAPISolrJTests ex
   protected void testCreateAndDeleteAlias() throws IOException, SolrServerException {
     CollectionAdminRequest.CreateAlias createAliasRequest = new CollectionAdminRequest
         .CreateAlias();
-    createAliasRequest.setCollectionName("solrj_alias");
-    createAliasRequest.setAliasedCollections("collection1");
+    createAliasRequest.setAliasName("solrj_alias");
+    createAliasRequest.setAliasedCollections(DEFAULT_COLLECTION);
     CollectionAdminResponse response = createAliasRequest.process(cloudClient);
 
     assertEquals(0, response.getStatus());
 
     CollectionAdminRequest.DeleteAlias deleteAliasRequest = new CollectionAdminRequest.DeleteAlias();
-    deleteAliasRequest.setCollectionName("solrj_alias");
+    deleteAliasRequest.setAliasName("solrj_alias");
     deleteAliasRequest.process(cloudClient);
     
     assertEquals(0, response.getStatus());
@@ -274,4 +288,213 @@ public class CollectionsAPISolrJTests ex
     deleteCollectionRequest.setCollectionName(collectionName);
     deleteCollectionRequest.process(cloudClient);
   }
+
+  private void testAddAndDeleteReplica() throws Exception {
+    String collectionName = "solrj_replicatests";
+    createCollection(collectionName, cloudClient, 1, 2);
+
+    cloudClient.setDefaultCollection(collectionName);
+
+    String newReplicaName = Assign.assignNode(collectionName, cloudClient.getZkStateReader().getClusterState());
+    ArrayList<String> nodeList = new ArrayList<>(cloudClient.getZkStateReader().getClusterState().getLiveNodes());
+    Collections.shuffle(nodeList, random());
+    CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica();
+    addReplica.setCollectionName(collectionName);
+    addReplica.setShardName("shard1");
+    addReplica.setNode(nodeList.get(0));
+    CollectionAdminResponse response = addReplica.process(cloudClient);
+
+    assertEquals(0, response.getStatus());
+    assertTrue(response.isSuccess());
+
+    long timeout = System.currentTimeMillis() + 3000;
+    Replica newReplica = null;
+
+    while (System.currentTimeMillis() < timeout && newReplica == null) {
+      Slice slice = cloudClient.getZkStateReader().getClusterState().getSlice(collectionName, "shard1");
+      newReplica = slice.getReplica(newReplicaName);
+    }
+
+    assertNotNull(newReplica);
+
+    assertEquals("Replica should be created on the right node",
+        cloudClient.getZkStateReader().getBaseUrlForNodeName(nodeList.get(0)),
+        newReplica.getStr(ZkStateReader.BASE_URL_PROP)
+    );
+    
+    // Test DELETEREPLICA
+    CollectionAdminRequest.DeleteReplica deleteReplicaRequest = new CollectionAdminRequest.DeleteReplica();
+    deleteReplicaRequest.setCollectionName(collectionName);
+    deleteReplicaRequest.setShardName("shard1");
+    deleteReplicaRequest.setReplica(newReplicaName);
+    response = deleteReplicaRequest.process(cloudClient);
+
+    assertEquals(0, response.getStatus());
+    
+    timeout = System.currentTimeMillis() + 3000;
+    
+    while (System.currentTimeMillis() < timeout && newReplica != null) {
+      Slice slice = cloudClient.getZkStateReader().getClusterState().getSlice(collectionName, "shard1");
+      newReplica = slice.getReplica(newReplicaName);
+    }
+
+    assertNull(newReplica);
+  }
+
+  private void testClusterProp() throws InterruptedException, IOException, SolrServerException {
+    CollectionAdminRequest.ClusterProp clusterPropRequest = new CollectionAdminRequest.ClusterProp();
+    clusterPropRequest.setPropertyName(ZkStateReader.LEGACY_CLOUD);
+    clusterPropRequest.setPropertyValue("false");
+    CollectionAdminResponse response = clusterPropRequest.process(cloudClient);
+
+    assertEquals(0, response.getStatus());
+
+    long timeOut = System.currentTimeMillis() + 3000;
+    boolean changed = false;
+    
+    while(System.currentTimeMillis() < timeOut){
+      Thread.sleep(10);
+      changed = Objects.equals("false",
+          cloudClient.getZkStateReader().getClusterProps().get(ZkStateReader.LEGACY_CLOUD));
+      if(changed) break;
+    }
+    assertTrue("The Cluster property wasn't set", changed);
+    
+    // Unset ClusterProp that we set.
+    clusterPropRequest = new CollectionAdminRequest.ClusterProp();
+    clusterPropRequest.setPropertyName(ZkStateReader.LEGACY_CLOUD);
+    clusterPropRequest.setPropertyValue(null);
+    clusterPropRequest.process(cloudClient);
+
+    timeOut = System.currentTimeMillis() + 3000;
+    changed = false;
+    while(System.currentTimeMillis() < timeOut){
+      Thread.sleep(10);
+      changed = (cloudClient.getZkStateReader().getClusterProps().get(ZkStateReader.LEGACY_CLOUD) == null);
+      if(changed)  
+        break;
+    }
+    assertTrue("The Cluster property wasn't unset", changed);
+  }
+
+  private void testAddAndRemoveRole() throws InterruptedException, IOException, SolrServerException {
+    cloudClient.setDefaultCollection(DEFAULT_COLLECTION);
+    Replica replica = cloudClient.getZkStateReader().getLeaderRetry(DEFAULT_COLLECTION, SHARD1);
+    CollectionAdminRequest.AddRole addRoleRequest = new CollectionAdminRequest.AddRole();
+    addRoleRequest.setNode(replica.getNodeName());
+    addRoleRequest.setRole("overseer");
+    addRoleRequest.process(cloudClient);
+
+    CollectionAdminRequest.ClusterStatus clusterStatusRequest = new CollectionAdminRequest.ClusterStatus();
+    clusterStatusRequest.setCollectionName(DEFAULT_COLLECTION);
+    CollectionAdminResponse response = clusterStatusRequest.process(cloudClient);
+
+    NamedList<Object> rsp = response.getResponse();
+    NamedList<Object> cluster = (NamedList<Object>) rsp.get("cluster");
+    assertNotNull("Cluster state should not be null", cluster);
+    Map<String, Object> roles = (Map<String, Object>) cluster.get("roles");
+    assertNotNull("Role information should not be null", roles);
+    List<String> overseer = (List<String>) roles.get("overseer");
+    assertNotNull(overseer);
+    assertEquals(1, overseer.size());
+    assertTrue(overseer.contains(replica.getNodeName()));
+    
+    // Remove role
+    CollectionAdminRequest.RemoveRole removeRoleRequest = new CollectionAdminRequest.RemoveRole();
+    removeRoleRequest.setNode(replica.getNodeName());
+    removeRoleRequest.setRole("overseer");
+    removeRoleRequest.process(cloudClient);
+
+    clusterStatusRequest = new CollectionAdminRequest.ClusterStatus();
+    clusterStatusRequest.setCollectionName(DEFAULT_COLLECTION);
+    response = clusterStatusRequest.process(cloudClient);
+
+    rsp = response.getResponse();
+    cluster = (NamedList<Object>) rsp.get("cluster");
+    assertNotNull("Cluster state should not be null", cluster);
+    roles = (Map<String, Object>) cluster.get("roles");
+    assertNotNull("Role information should not be null", roles);
+    overseer = (List<String>) roles.get("overseer");
+    assertFalse(overseer.contains(replica.getNodeName()));
+  }
+  
+  private void testOverseerStatus() throws IOException, SolrServerException {
+    CollectionAdminRequest.OverseerStatus overseerStatusRequest = new CollectionAdminRequest.OverseerStatus();
+    CollectionAdminResponse response = overseerStatusRequest.process(cloudClient);
+    assertEquals(0, response.getStatus());
+    assertNotNull("overseer_operations shouldn't be null", response.getResponse().get("overseer_operations"));
+  }
+  
+  private void testList() throws IOException, SolrServerException {
+    CollectionAdminRequest.List listRequest = new CollectionAdminRequest.List();
+    CollectionAdminResponse response = listRequest.process(cloudClient);
+    assertEquals(0, response.getStatus());
+    assertNotNull("collection list should not be null", response.getResponse().get("collections"));
+  }
+  
+  private void testAddAndDeleteReplicaProp() throws InterruptedException, IOException, SolrServerException {
+    Replica replica = cloudClient.getZkStateReader().getLeaderRetry(DEFAULT_COLLECTION, SHARD1);
+    CollectionAdminRequest.AddReplicaProp addReplicaPropRequest = new CollectionAdminRequest.AddReplicaProp();
+    addReplicaPropRequest.setCollectionName(DEFAULT_COLLECTION);
+    addReplicaPropRequest.setShardName(SHARD1);
+    addReplicaPropRequest.setReplica(replica.getName());
+    addReplicaPropRequest.setPropertyName("preferredleader");
+    addReplicaPropRequest.setPropertyValue("true");
+    CollectionAdminResponse response = addReplicaPropRequest.process(cloudClient);
+    assertEquals(0, response.getStatus());
+
+    long timeout = System.currentTimeMillis() + 20000;
+    String propertyValue = null;
+    
+    String replicaName = replica.getName();
+    while (System.currentTimeMillis() < timeout) {
+      ClusterState clusterState = cloudClient.getZkStateReader().getClusterState();
+      replica = clusterState.getReplica(DEFAULT_COLLECTION, replicaName);
+      propertyValue = replica.getStr("property.preferredleader"); 
+      if(StringUtils.equals("true", propertyValue))
+        break;
+      Thread.sleep(50);
+    }
+    
+    assertEquals("Replica property was not updated, Latest value: " +
+        cloudClient.getZkStateReader().getClusterState().getReplica(DEFAULT_COLLECTION, replicaName),
+        "true",
+        propertyValue);
+
+    CollectionAdminRequest.DeleteReplicaProp deleteReplicaPropRequest = new CollectionAdminRequest.DeleteReplicaProp();
+    deleteReplicaPropRequest.setCollectionName(DEFAULT_COLLECTION);
+    deleteReplicaPropRequest.setShardName(SHARD1);
+    deleteReplicaPropRequest.setReplica(replicaName);
+    deleteReplicaPropRequest.setPropertyName("property.preferredleader");
+    response = deleteReplicaPropRequest.process(cloudClient);
+    assertEquals(0, response.getStatus());
+
+    timeout = System.currentTimeMillis() + 20000;
+    boolean updated = false;
+
+    while (System.currentTimeMillis() < timeout) {
+      ClusterState clusterState = cloudClient.getZkStateReader().getClusterState();
+      replica = clusterState.getReplica(DEFAULT_COLLECTION, replicaName);
+      updated = replica.getStr("property.preferredleader") == null;
+      if(updated)
+        break;
+      Thread.sleep(50);
+    }
+
+    assertTrue("Replica property was not removed", updated);
+    
+  }
+  
+  private void testBalanceShardUnique() throws IOException,
+      SolrServerException, KeeperException, InterruptedException {
+    CollectionAdminRequest.BalanceShardUnique balanceShardUniqueRequest = 
+        new CollectionAdminRequest.BalanceShardUnique();
+    cloudClient.setDefaultCollection(DEFAULT_COLLECTION);
+    balanceShardUniqueRequest.setCollection(DEFAULT_COLLECTION);
+    balanceShardUniqueRequest.setPropertyName("preferredLeader");
+    CollectionAdminResponse response = balanceShardUniqueRequest.process(cloudClient);
+    assertEquals(0, response.getStatus());
+
+    verifyUniqueAcrossCollection(cloudClient, DEFAULT_COLLECTION, "property.preferredleader");    
+  }
 }

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java Mon Dec 29 23:37:04 2014
@@ -172,7 +172,7 @@ public class HttpPartitionTest extends A
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {
@@ -253,7 +253,7 @@ public class HttpPartitionTest extends A
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {
@@ -309,7 +309,7 @@ public class HttpPartitionTest extends A
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {
@@ -405,7 +405,7 @@ public class HttpPartitionTest extends A
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java Mon Dec 29 23:37:04 2014
@@ -170,7 +170,7 @@ public class LeaderFailoverAfterPartitio
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java Mon Dec 29 23:37:04 2014
@@ -105,7 +105,7 @@ public class LeaderInitiatedRecoveryOnCo
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {
@@ -147,7 +147,7 @@ public class LeaderInitiatedRecoveryOnCo
 
     // try to clean up
     try {
-      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete();
       req.setCollectionName(testCollectionName);
       req.process(cloudClient);
     } catch (Exception e) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java Mon Dec 29 23:37:04 2014
@@ -22,6 +22,7 @@ import org.apache.solr.client.solrj.Solr
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrServer;
 import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrInputDocument;
@@ -119,14 +120,13 @@ public class MigrateRouteKeyTest extends
   }
 
   protected void invokeMigrateApi(String sourceCollection, String splitKey, String targetCollection) throws SolrServerException, IOException {
-    ModifiableSolrParams params = new ModifiableSolrParams();
-    params.set("action", CollectionParams.CollectionAction.MIGRATE.toString());
-    params.set("collection", sourceCollection);
-    params.set("target.collection", targetCollection);
-    params.set("split.key", splitKey);
-    params.set("forward.timeout", 45);
-
-    invoke(params);
+    cloudClient.setDefaultCollection(sourceCollection);
+    CollectionAdminRequest.Migrate migrateRequest = new CollectionAdminRequest.Migrate();
+    migrateRequest.setCollectionName(sourceCollection);
+    migrateRequest.setTargetCollection(targetCollection);
+    migrateRequest.setSplitKey(splitKey);
+    migrateRequest.setForwardTimeout(45);
+    migrateRequest.process(cloudClient);
   }
 
   protected void invoke(ModifiableSolrParams params) throws SolrServerException, IOException {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ReplicaPropertiesBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ReplicaPropertiesBase.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ReplicaPropertiesBase.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ReplicaPropertiesBase.java Mon Dec 29 23:37:04 2014
@@ -40,7 +40,7 @@ import org.apache.zookeeper.KeeperExcept
 // and shards, but for now this will do.
 public abstract class ReplicaPropertiesBase extends AbstractFullDistribZkTestBase {
 
-  NamedList<Object> doPropertyAction(CloudSolrServer client, String... paramsIn) throws IOException, SolrServerException {
+  public static NamedList<Object> doPropertyAction(CloudSolrServer client, String... paramsIn) throws IOException, SolrServerException {
     assertTrue("paramsIn must be an even multiple of 2, it is: " + paramsIn.length, (paramsIn.length % 2) == 0);
     ModifiableSolrParams params = new ModifiableSolrParams();
     for (int idx = 0; idx < paramsIn.length; idx += 2) {
@@ -51,7 +51,7 @@ public abstract class ReplicaPropertiesB
     return client.request(request);
   }
 
-  void verifyPropertyNotPresent(CloudSolrServer client, String collectionName, String replicaName,
+  public static void verifyPropertyNotPresent(CloudSolrServer client, String collectionName, String replicaName,
                                 String property)
       throws KeeperException, InterruptedException {
     ClusterState clusterState = null;
@@ -76,7 +76,7 @@ public abstract class ReplicaPropertiesB
   // collection
   // shard
   // replica
-  void verifyPropertyVal(CloudSolrServer client, String collectionName,
+  public static void verifyPropertyVal(CloudSolrServer client, String collectionName,
                          String replicaName, String property, String val)
       throws InterruptedException, KeeperException {
     Replica replica = null;
@@ -102,16 +102,16 @@ public abstract class ReplicaPropertiesB
   // Verify that
   // 1> the property is only set once in all the replicas in a slice.
   // 2> the property is balanced evenly across all the nodes hosting collection
-  void verifyUniqueAcrossCollection(CloudSolrServer client, String collectionName,
+  public static void verifyUniqueAcrossCollection(CloudSolrServer client, String collectionName,
                                     String property) throws KeeperException, InterruptedException {
     verifyUnique(client, collectionName, property, true);
   }
 
-  void verifyUniquePropertyWithinCollection(CloudSolrServer client, String collectionName,
+  public static void verifyUniquePropertyWithinCollection(CloudSolrServer client, String collectionName,
                             String property) throws KeeperException, InterruptedException {
     verifyUnique(client, collectionName, property, false);
   }
-  void verifyUnique(CloudSolrServer client, String collectionName, String property, boolean balanced)
+  public static void verifyUnique(CloudSolrServer client, String collectionName, String property, boolean balanced)
       throws KeeperException, InterruptedException {
 
     DocCollection col = null;

Modified: lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java?rev=1648446&r1=1648445&r2=1648446&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java Mon Dec 29 23:37:04 2014
@@ -43,14 +43,52 @@ import java.util.concurrent.TimeUnit;
  *
  * @since solr 4.5
  */
-public class CollectionAdminRequest extends SolrRequest
-{
-  protected String collection = null;
+public class CollectionAdminRequest extends SolrRequest {
   protected CollectionAction action = null;
-  protected String asyncId = null;
 
   private static String PROPERTY_PREFIX = "property.";
 
+  public void setAction( CollectionAction action )
+  {
+    this.action = action;
+  }
+
+  public CollectionAdminRequest()
+  {
+    super( METHOD.GET, "/admin/collections" );
+  }
+
+  public CollectionAdminRequest( String path )
+  {
+    super( METHOD.GET, path );
+  }
+
+  @Override
+  public SolrParams getParams() {
+    if( action == null ) {
+      throw new RuntimeException( "no action specified!" );
+    }
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.set( CoreAdminParams.ACTION, action.toString() );
+    return params;
+  }
+
+  @Override
+  public Collection<ContentStream> getContentStreams() throws IOException {
+    return null;
+  }
+
+  @Override
+  public CollectionAdminResponse process(SolrServer server) throws SolrServerException, IOException
+  {
+    long startTime = TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
+    CollectionAdminResponse res = new CollectionAdminResponse();
+    res.setResponse( server.request( this ) );
+    long endTime = TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
+    res.setElapsedTime(endTime - startTime);
+    return res;
+  }
+  
   protected void addProperties(ModifiableSolrParams params, Properties props) {
     Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator();
     while(iter.hasNext()) {
@@ -61,7 +99,29 @@ public class CollectionAdminRequest exte
     }
   }
 
-  protected static class CollectionShardAdminRequest extends CollectionAdminRequest {
+  //---------------------------------------------------------------------------------------
+  //
+  //---------------------------------------------------------------------------------------
+
+  protected static class CollectionSpecificAdminRequest extends CollectionAdminRequest {
+    protected String collection = null;
+
+    public final void setCollectionName( String collectionName )
+    {
+      this.collection = collectionName;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set( CoreAdminParams.NAME, collection );
+      return params;
+    }
+
+
+  }
+  
+  protected static class CollectionShardAdminRequest extends CollectionSpecificAdminRequest {
     protected String shardName = null;
 
     public void setShardName(String shard) { this.shardName = shard; }
@@ -69,10 +129,8 @@ public class CollectionAdminRequest exte
 
     public ModifiableSolrParams getCommonParams() {
       ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
-      params.remove( "name" );
       params.set( "collection", collection );
       params.set( "shard", shardName);
-      params.set( "async", asyncId);
       return params;
     }
 
@@ -81,9 +139,41 @@ public class CollectionAdminRequest exte
       return getCommonParams();
     }
   }
+  
+  protected static class CollectionAdminRoleRequest extends CollectionAdminRequest {
+    private String node;
+    private String role;
+
+    public void setNode(String node) {
+      this.node = node;
+    }
+
+    public String getNode() {
+      return this.node;
+    }
+
+    public void setRole(String role) {
+      this.role = role;
+    }
+
+    public String getRole() {
+      return this.role;
+    }
+
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set("role", this.role);
+      params.set("node", this.node);
+      return params;
+    }
+
+  }
 
-  //a create collection request
-  public static class Create extends CollectionAdminRequest {
+  /** Specific Collection API call implementations **/ 
+  
+  // CREATE request
+  public static class Create extends CollectionSpecificAdminRequest {
     protected String configName = null;
     protected String createNodeSet = null;
     protected String routerName;
@@ -96,6 +186,7 @@ public class CollectionAdminRequest exte
     private Properties properties;
     protected Boolean autoAddReplicas;
     protected Integer stateFormat;
+    protected String asyncId;
 
 
     public Create() {
@@ -112,6 +203,9 @@ public class CollectionAdminRequest exte
     public void setAutoAddReplicas(boolean autoAddReplicas) { this.autoAddReplicas = autoAddReplicas; }
     public void setReplicationFactor(Integer repl) { this.replicationFactor = repl; }
     public void setStateFormat(Integer stateFormat) { this.stateFormat = stateFormat; }
+    public void setAsyncId(String asyncId) {
+      this.asyncId = asyncId;
+    }
 
     public String getConfigName()  { return configName; }
     public String getCreateNodeSet() { return createNodeSet; }
@@ -122,6 +216,9 @@ public class CollectionAdminRequest exte
     public Integer getReplicationFactor() { return replicationFactor; }
     public Boolean getAutoAddReplicas() { return autoAddReplicas; }
     public Integer getStateFormat() { return stateFormat; }
+    public String getAsyncId() {
+      return asyncId;
+    }
 
     public Properties getProperties() {
       return properties;
@@ -135,37 +232,26 @@ public class CollectionAdminRequest exte
     public SolrParams getParams() {
       ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
 
-      if (configName != null) {
-        params.set( "collection.configName", configName);
-      }
-      if (createNodeSet != null) {
-        params.set( "createNodeSet", createNodeSet);
-      }
+      params.set( "collection.configName", configName);
+      params.set( "createNodeSet", createNodeSet);
       if (numShards != null) {
         params.set( ZkStateReader.NUM_SHARDS_PROP, numShards);
       }
       if (maxShardsPerNode != null) {
         params.set( "maxShardsPerNode", maxShardsPerNode);
       }
-      if (routerName != null) {
-        params.set( "router.name", routerName);
-      }
-      if (shards != null) {
-        params.set("shards", shards);
-      }
+      params.set( "router.name", routerName);
+      params.set("shards", shards);
       if (routerField != null) {
         params.set("router.field", routerField);
       }
       if (replicationFactor != null) {
         params.set( "replicationFactor", replicationFactor);
       }
-      if (asyncId != null) {
-        params.set("async", asyncId);
-      }
+      params.set("async", asyncId);
       if (autoAddReplicas != null) {
         params.set(ZkStateReader.AUTO_ADD_REPLICAS, autoAddReplicas);
       }
-
       if(properties != null) {
         addProperties(params, properties);
       }
@@ -174,23 +260,24 @@ public class CollectionAdminRequest exte
       }
       return params;
     }
+    
   }
 
-  //a reload collection request
-  public static class Reload extends CollectionAdminRequest {
+  // RELOAD request
+  public static class Reload extends CollectionSpecificAdminRequest {
     public Reload() {
       action = CollectionAction.RELOAD;
     }
   }
 
-  //a delete collection request
-  public static class Delete extends CollectionAdminRequest {
+  // DELETE request
+  public static class Delete extends CollectionSpecificAdminRequest {
     public Delete() {
       action = CollectionAction.DELETE;
     }
   }
 
-  //a create shard collection request
+  // CREATESHARD request
   public static class CreateShard extends CollectionShardAdminRequest {
     protected String nodeSet;
     private Properties properties;
@@ -226,13 +313,18 @@ public class CollectionAdminRequest exte
     }
   }
 
-  //a split shard collection request
+  // SPLITSHARD request
   public static class SplitShard extends CollectionShardAdminRequest {
     protected String ranges;
     protected String splitKey;
-
+    protected String asyncId;
+    
     private Properties properties;
 
+    public SplitShard() {
+      action = CollectionAction.SPLITSHARD;
+    }
+
     public void setRanges(String ranges) { this.ranges = ranges; }
     public String getRanges() { return ranges; }
 
@@ -252,10 +344,14 @@ public class CollectionAdminRequest exte
       this.properties = properties;
     }
 
-    public SplitShard() {
-      action = CollectionAction.SPLITSHARD;
+    public void setAsyncId(String asyncId) {
+      this.asyncId = asyncId;
     }
 
+    public String getAsyncId() {
+      return asyncId;
+    }
+    
     @Override
     public SolrParams getParams() {
       ModifiableSolrParams params = getCommonParams();
@@ -267,18 +363,20 @@ public class CollectionAdminRequest exte
       if(properties != null) {
         addProperties(params, properties);
       }
+      
+      params.set("async", asyncId);
       return params;
     }
   }
 
-  //a delete shard collection request
+  // DELETESHARD request
   public static class DeleteShard extends CollectionShardAdminRequest {
     public DeleteShard() {
       action = CollectionAction.DELETESHARD;
     }
   }
 
-  //a request status collection request
+  // REQUESTSTATUS request
   public static class RequestStatus extends CollectionAdminRequest {
     protected  String requestId = null;
 
@@ -290,52 +388,75 @@ public class CollectionAdminRequest exte
     public String getRequestId() { return this.requestId; }
 
     @Override
-    public void setAsyncId(String asyncId) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "You can not set async id for " +
-          "a REQUESTSTATUS call. Try setRequestId()." );
-    }
-
-    @Override
     public SolrParams getParams() {
       ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
       params.set("requestid", requestId);
       return params;
     }
   }
-
-  //a collection alias create request
+  
+  // CREATEALIAS request
   public static class CreateAlias extends CollectionAdminRequest {
-    protected String aliasedCollections = null;
+    protected String aliasName;
+    protected String aliasedCollections;
+
+    public CreateAlias() {
+      action = CollectionAction.CREATEALIAS;
+    }
 
+    public void setAliasName(String aliasName) {
+      this.aliasName = aliasName;
+    }
+
+    public String getAliasName() {
+      return aliasName;
+    }
+    
     public void setAliasedCollections(String alias) { this.aliasedCollections = alias; }
     public String getAliasedCollections() { return this.aliasedCollections; }
-
+    
+    @Deprecated
+    public void setCollectionName(String aliasName) {
+      this.aliasName = aliasName;
+    }
+    
     @Override
     public SolrParams getParams() {
       ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
+      params.set("name", aliasName);
       params.set( "collections", aliasedCollections );
       return params;
     }
-
-
-    public CreateAlias() {
-      action = CollectionAction.CREATEALIAS;
-    }
   }
 
-  //a collection alias delete request
+  // DELETEALIAS request
   public static class DeleteAlias extends CollectionAdminRequest {
+    protected String aliasName;
+    
     public DeleteAlias() {
       action = CollectionAction.DELETEALIAS;
     }
+    
+    public void setAliasName(String aliasName) {
+      this.aliasName = aliasName;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set("name", aliasName);
+      return params;
+    }
   }
 
+  // ADDREPLICA request
   public static class AddReplica extends CollectionShardAdminRequest {
     private String node;
     private String routeKey;
     private String instanceDir;
     private String dataDir;
     private Properties properties;
+    private String asyncId;
 
     public AddReplica() {
       action = CollectionAction.ADDREPLICA;
@@ -391,6 +512,7 @@ public class CollectionAdminRequest exte
         }
         params.add(ShardParams._ROUTE_, routeKey);
       }
+      params.set("async", asyncId);
       if (node != null) {
         params.add("node", node);
       }
@@ -405,69 +527,338 @@ public class CollectionAdminRequest exte
       }
       return params;
     }
+
+    public void setAsyncId(String asyncId) {
+      this.asyncId = asyncId;
+    }
+    
+    public String getAsyncId() {
+      return asyncId;
+    }
   }
 
-  public CollectionAdminRequest()
-  {
-    super( METHOD.GET, "/admin/collections" );
+  // DELETEREPLICA request
+  public static class DeleteReplica extends CollectionShardAdminRequest {
+    private String replica;
+    private Boolean onlyIfDown;
+    
+    public DeleteReplica() {
+      action = CollectionAction.DELETEREPLICA;
+    }
+
+    public void setReplica(String replica) {
+      this.replica = replica;
+    }
+
+    public String getReplica() {
+      return this.replica;
+    }
+    
+    public void setOnlyIfDown(boolean onlyIfDown) {
+      this.onlyIfDown = onlyIfDown;
+    }
+    
+    public Boolean getOnlyIfDown() {
+      return this.onlyIfDown;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set(ZkStateReader.REPLICA_PROP, this.replica);
+      
+      if(onlyIfDown != null) {
+        params.set("onlyIfDown", this.onlyIfDown);
+      }
+      return params;
+    }
   }
+  
+  // CLUSTERPROP request
+  public static class ClusterProp extends CollectionAdminRequest {
+    private String propertyName;
+    private String propertyValue;
+    
+    public ClusterProp() {
+      this.action = CollectionAction.CLUSTERPROP;
+    }
+    
+    public void setPropertyName(String propertyName) {
+      this.propertyName = propertyName;
+    }
 
-  public CollectionAdminRequest( String path )
-  {
-    super( METHOD.GET, path );
+    public String getPropertyName() {
+      return this.propertyName;
+    }
+
+    public void setPropertyValue(String propertyValue) {
+      this.propertyValue = propertyValue;
+    }
+    
+    public String getPropertyValue() {
+      return this.propertyValue;
+    }
+    
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.add("name", propertyName);
+      params.add("val", propertyValue);
+      
+      return params;
+    }
+    
   }
+  
+  // MIGRATE request
+  public static class Migrate extends CollectionSpecificAdminRequest {
+    private String targetCollection;
+    private String splitKey;
+    private Integer forwardTimeout;
+    private Properties properties;
+    private String asyncId;
+    
+    public Migrate() {
+      action = CollectionAction.MIGRATE;
+    }
+    
+    public void setTargetCollection(String targetCollection) {
+      this.targetCollection = targetCollection;
+    }
+    
+    public String getTargetCollection() {
+      return this.targetCollection;
+    }
+    
+    public void setSplitKey(String splitKey) {
+      this.splitKey = splitKey;
+    }
+    
+    public String getSplitKey() {
+      return this.splitKey;
+    }
+    
+    public void setForwardTimeout(int forwardTimeout) {
+      this.forwardTimeout = forwardTimeout;
+    }
+    
+    public Integer getForwardTimeout() {
+      return this.forwardTimeout;
+    }
+    
+    public void setProperties(Properties properties) {
+      this.properties = properties;
+    }
+    
+    public Properties getProperties() {
+      return this.properties;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set( "collection", collection );
+      params.set("target.collection", targetCollection);
+      params.set("split.key", splitKey);
+      if(forwardTimeout != null) {
+        params.set("forward.timeout", forwardTimeout);
+      }
+      params.set("async", asyncId);
+      
+      if(properties != null) {
+        addProperties(params, properties);
+      }
+      
+      return params;
+    }
 
-  public final void setCollectionName( String collectionName )
-  {
-    this.collection = collectionName;
+    public void setAsyncId(String asyncId) {
+      this.asyncId = asyncId;
+    }
+    
+    public String getAsyncId() {
+      return asyncId;
+    }
+  }
+  
+  // ADDROLE request
+  public static class AddRole extends CollectionAdminRoleRequest {
+    public AddRole() {
+      action = CollectionAction.ADDROLE;
+    }
   }
 
-  //---------------------------------------------------------------------------------------
-  //
-  //---------------------------------------------------------------------------------------
+  // REMOVEROLE request
+  public static class RemoveRole extends CollectionAdminRoleRequest {
+    public RemoveRole() {
+      action = CollectionAction.REMOVEROLE;
+    }
+  }
+  
+  // OVERSEERSTATUS request
+  public static class OverseerStatus extends CollectionAdminRequest {
+    public OverseerStatus () {
+      action = CollectionAction.OVERSEERSTATUS;
+    }
+  }
 
-  public void setAction( CollectionAction action )
-  {
-    this.action = action;
+  // CLUSTERSTATUS request
+  public static class ClusterStatus extends CollectionShardAdminRequest {
+    
+    public ClusterStatus () {
+      action = CollectionAction.CLUSTERSTATUS;
+    }
+    
   }
 
-  public void setAsyncId(String asyncId) {
-    this.asyncId = asyncId;
+  // LIST request
+  public static class List extends CollectionAdminRequest {
+    public List () {
+      action = CollectionAction.LIST;
+    }
   }
+  
+  // ADDREPLICAPROP request
+  public static class AddReplicaProp extends CollectionShardAdminRequest {
+    private String replica;
+    private String propertyName;
+    private String propertyValue;
+    private Boolean shardUnique;
+    
+    public AddReplicaProp() {
+      action = CollectionAction.ADDREPLICAPROP;
+    }
 
-  //---------------------------------------------------------------------------------------
-  //
-  //---------------------------------------------------------------------------------------
+    public String getReplica() {
+      return replica;
+    }
 
-  @Override
-  public SolrParams getParams()
-  {
-    if( action == null ) {
-      throw new RuntimeException( "no action specified!" );
+    public void setReplica(String replica) {
+      this.replica = replica;
     }
-    ModifiableSolrParams params = new ModifiableSolrParams();
-    params.set( CoreAdminParams.ACTION, action.toString() );
-    params.set( CoreAdminParams.NAME, collection );
-    return params;
+
+    public String getPropertyName() {
+      return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+      this.propertyName = propertyName;
+    }
+
+    public String getPropertyValue() {
+      return propertyValue;
+    }
+
+    public void setPropertyValue(String propertyValue) {
+      this.propertyValue = propertyValue;
+    }
+
+    public Boolean getShardUnique() {
+      return shardUnique;
+    }
+
+    public void setShardUnique(Boolean shardUnique) {
+      this.shardUnique = shardUnique;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set("replica", replica);
+      params.set("property", propertyName);
+      params.set("property.value", propertyValue);
+      
+      if(shardUnique != null)
+        params.set("shardUnique", shardUnique);
+      
+      return params;
+    }
+    
   }
+  
+  // DELETEREPLICAPROP request
+  public static class DeleteReplicaProp extends CollectionShardAdminRequest {
+    private String replica;
+    private String propertyName;
 
-  //---------------------------------------------------------------------------------------
-  //
-  //---------------------------------------------------------------------------------------
+    public DeleteReplicaProp() {
+      this.action = CollectionAction.DELETEREPLICAPROP;
+    }
+    
+    public String getReplica() {
+      return replica;
+    }
 
-  @Override
-  public Collection<ContentStream> getContentStreams() throws IOException {
-    return null;
+    public void setReplica(String replica) {
+      this.replica = replica;
+    }
+
+    public String getPropertyName() {
+      return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+      this.propertyName = propertyName;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set("replica", replica);
+      params.set("property", propertyName);
+      return params;
+    }
   }
+  
+  // BALANCESHARDUNIQUE request
+  public static class BalanceShardUnique extends CollectionAdminRequest {
+    private String collection;
+    private String propertyName;
+    private Boolean onlyActiveNodes;
+    private Boolean shardUnique;
 
-  @Override
-  public CollectionAdminResponse process(SolrServer server) throws SolrServerException, IOException
-  {
-    long startTime = TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
-    CollectionAdminResponse res = new CollectionAdminResponse();
-    res.setResponse( server.request( this ) );
-    long endTime = TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
-    res.setElapsedTime(endTime - startTime);
-    return res;
+
+    public String getPropertyName() {
+      return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+      this.propertyName = propertyName;
+    }
+
+    public Boolean getOnlyActiveNodes() {
+      return onlyActiveNodes;
+    }
+
+    public void setOnlyActiveNodes(Boolean onlyActiveNodes) {
+      this.onlyActiveNodes = onlyActiveNodes;
+    }
+
+    public Boolean getShardUnique() {
+      return shardUnique;
+    }
+
+    public void setShardUnique(Boolean shardUnique) {
+      this.shardUnique = shardUnique;
+    }
+
+    public void setCollection(String collection) {
+      this.collection = collection;
+    }
+    
+    public String getCollection() {
+      return collection;
+    }
+    
+    @Override
+    public SolrParams getParams() {
+      ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+      params.set("collection", collection);
+      params.set("property", propertyName);
+      if(onlyActiveNodes != null)
+        params.set("onlyactivenodes", onlyActiveNodes);
+      if(shardUnique != null)
+        params.set("shardUnique", shardUnique);
+      return params;
+    }
   }
 }