diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 7893b884e52..b71c63b3ec6 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -22,6 +22,10 @@ See the Quick Start guide at http://lucene.apache.org/solr/quickstart.html ================== 6.1.0 ================== Detailed Change List ---------------------- +* SOLR-8782: Add asynchronous sugar methods to the SolrJ Collections API. You + can now call .processAsync() to run a method asynchronously, or + .processAndWait() to wait for a call to finish without holding HTTP + collections open. (Alan Woodward) New Features ---------------------- diff --git a/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml new file mode 100644 index 00000000000..2a276af206a --- /dev/null +++ b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + id + diff --git a/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml new file mode 100644 index 00000000000..059e58f447c --- /dev/null +++ b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml @@ -0,0 +1,48 @@ + + + + + + + + + ${solr.data.dir:} + + + + + ${tests.luceneMatchVersion:LATEST} + + + + ${solr.commitwithin.softcommit:true} + + + + + + + explicit + true + text + + + + + diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java index 493b2988853..dcb115a1269 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java @@ -21,90 +21,80 @@ import java.util.List; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.TestUtil; -import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CollectionAdminRequest.Create; import org.apache.solr.client.solrj.request.CollectionAdminRequest.SplitShard; import org.apache.solr.client.solrj.response.RequestStatusState; -import org.apache.solr.client.solrj.response.CollectionAdminResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.cloud.Slice; +import org.junit.BeforeClass; import org.junit.Test; /** * Tests the Cloud Collections API. */ @Slow -public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkTestBase { +public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { + private static final int MAX_TIMEOUT_SECONDS = 60; - public CollectionsAPIAsyncDistributedZkTest() { - sliceCount = 1; + @BeforeClass + public static void setupCluster() throws Exception { + configureCluster(2) + .addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf")) + .configure(); } @Test - @ShardsFixed(num = 1) public void testSolrJAPICalls() throws Exception { - try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { - Create createCollectionRequest = new Create() - .setCollectionName("testasynccollectioncreation") - .setNumShards(1) - .setConfigName("conf1") - .setAsyncId("1001"); - createCollectionRequest.process(client); - - RequestStatusState state = getRequestStateAfterCompletion("1001", MAX_TIMEOUT_SECONDS, client); - - assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state); - - createCollectionRequest = new Create() - .setCollectionName("testasynccollectioncreation") - .setNumShards(1) - .setConfigName("conf1") - .setAsyncId("1002"); - createCollectionRequest.process(client); - - state = getRequestStateAfterCompletion("1002", MAX_TIMEOUT_SECONDS, client); - - assertSame("Recreating a collection with the same should have failed.", RequestStatusState.FAILED, state); - - CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica() - .setCollectionName("testasynccollectioncreation") - .setShardName("shard1") - .setAsyncId("1003"); - client.request(addReplica); - state = getRequestStateAfterCompletion("1003", MAX_TIMEOUT_SECONDS, client); - assertSame("Add replica did not complete", RequestStatusState.COMPLETED, state); - - SplitShard splitShardRequest = new SplitShard() - .setCollectionName("testasynccollectioncreation") - .setShardName("shard1") - .setAsyncId("1004"); - splitShardRequest.process(client); - - state = getRequestStateAfterCompletion("1004", MAX_TIMEOUT_SECONDS * 2, client); - - assertEquals("Shard split did not complete. Last recorded state: " + state, RequestStatusState.COMPLETED, state); - } + + final CloudSolrClient client = cluster.getSolrClient(); + + RequestStatusState state = new Create() + .setCollectionName("testasynccollectioncreation") + .setNumShards(1) + .setReplicationFactor(1) + .setConfigName("conf1") + .processAndWait(client, MAX_TIMEOUT_SECONDS); + assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state); + + state = new Create() + .setCollectionName("testasynccollectioncreation") + .setNumShards(1) + .setConfigName("conf1") + .processAndWait(client, MAX_TIMEOUT_SECONDS); + assertSame("Recreating a collection with the same should have failed.", RequestStatusState.FAILED, state); + + state = new CollectionAdminRequest.AddReplica() + .setCollectionName("testasynccollectioncreation") + .setShardName("shard1") + .processAndWait(client, MAX_TIMEOUT_SECONDS); + assertSame("Add replica did not complete", RequestStatusState.COMPLETED, state); + + state = new SplitShard() + .setCollectionName("testasynccollectioncreation") + .setShardName("shard1") + .processAndWait(client, MAX_TIMEOUT_SECONDS * 2); + assertEquals("Shard split did not complete. Last recorded state: " + state, RequestStatusState.COMPLETED, state); + } @Test public void testAsyncRequests() throws Exception { - String collection = "testAsyncOperations"; - Create createCollectionRequest = new Create() + final String collection = "testAsyncOperations"; + final CloudSolrClient client = cluster.getSolrClient(); + + RequestStatusState state = new Create() .setCollectionName(collection) .setNumShards(1) .setRouterName("implicit") .setShards("shard1") .setConfigName("conf1") - .setAsyncId("42"); - CollectionAdminResponse response = createCollectionRequest.process(cloudClient); - assertEquals("42", response.getResponse().get("requestid")); - RequestStatusState state = getRequestStateAfterCompletion("42", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state); //Add a few documents to shard1 @@ -116,59 +106,48 @@ public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkT doc.addField("_route_", "shard1"); docs.add(doc); } - cloudClient.add(collection, docs); - cloudClient.commit(collection); + client.add(collection, docs); + client.commit(collection); SolrQuery query = new SolrQuery("*:*"); query.set("shards", "shard1"); - assertEquals(numDocs, cloudClient.query(collection, query).getResults().getNumFound()); + assertEquals(numDocs, client.query(collection, query).getResults().getNumFound()); - CollectionAdminRequest.Reload reloadCollection = new CollectionAdminRequest.Reload(); - reloadCollection.setCollectionName(collection).setAsyncId("43"); - response = reloadCollection.process(cloudClient); - assertEquals("43", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("43", MAX_TIMEOUT_SECONDS, cloudClient); + state = new CollectionAdminRequest.Reload() + .setCollectionName(collection) + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("ReloadCollection did not complete", RequestStatusState.COMPLETED, state); - CollectionAdminRequest.CreateShard createShard = new CollectionAdminRequest.CreateShard() + state = new CollectionAdminRequest.CreateShard() .setCollectionName(collection) .setShardName("shard2") - .setAsyncId("44"); - response = createShard.process(cloudClient); - assertEquals("44", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("44", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateShard did not complete", RequestStatusState.COMPLETED, state); //Add a doc to shard2 to make sure shard2 was created properly SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", numDocs + 1); doc.addField("_route_", "shard2"); - cloudClient.add(collection, doc); - cloudClient.commit(collection); + client.add(collection, doc); + client.commit(collection); query = new SolrQuery("*:*"); query.set("shards", "shard2"); - assertEquals(1, cloudClient.query(collection, query).getResults().getNumFound()); + assertEquals(1, client.query(collection, query).getResults().getNumFound()); - CollectionAdminRequest.DeleteShard deleteShard = new CollectionAdminRequest.DeleteShard() + state = new CollectionAdminRequest.DeleteShard() .setCollectionName(collection) .setShardName("shard2") - .setAsyncId("45"); - response = deleteShard.process(cloudClient); - assertEquals("45", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("45", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteShard did not complete", RequestStatusState.COMPLETED, state); - CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica() + state = new CollectionAdminRequest.AddReplica() .setCollectionName(collection) .setShardName("shard1") - .setAsyncId("46"); - response = addReplica.process(cloudClient); - assertEquals("46", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("46", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("AddReplica did not complete", RequestStatusState.COMPLETED, state); //cloudClient watch might take a couple of seconds to reflect it - Slice shard1 = cloudClient.getZkStateReader().getClusterState().getSlice(collection, "shard1"); + Slice shard1 = client.getZkStateReader().getClusterState().getSlice(collection, "shard1"); int count = 0; while (shard1.getReplicas().size() != 2) { if (count++ > 1000) { @@ -177,51 +156,40 @@ public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkT Thread.sleep(100); } - CollectionAdminRequest.CreateAlias createAlias = new CollectionAdminRequest.CreateAlias() + state = new CollectionAdminRequest.CreateAlias() .setAliasName("myalias") .setAliasedCollections(collection) - .setAsyncId("47"); - response = createAlias.process(cloudClient); - assertEquals("47", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("47", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateAlias did not complete", RequestStatusState.COMPLETED, state); query = new SolrQuery("*:*"); query.set("shards", "shard1"); - assertEquals(numDocs, cloudClient.query("myalias", query).getResults().getNumFound()); + assertEquals(numDocs, client.query("myalias", query).getResults().getNumFound()); - CollectionAdminRequest.DeleteAlias deleteAlias = new CollectionAdminRequest.DeleteAlias() + state = new CollectionAdminRequest.DeleteAlias() .setAliasName("myalias") - .setAsyncId("48"); - response = deleteAlias.process(cloudClient); - assertEquals("48", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("48", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteAlias did not complete", RequestStatusState.COMPLETED, state); try { - cloudClient.query("myalias", query); + client.query("myalias", query); fail("Alias should not exist"); } catch (SolrException e) { //expected } String replica = shard1.getReplicas().iterator().next().getName(); - CollectionAdminRequest.DeleteReplica deleteReplica = new CollectionAdminRequest.DeleteReplica() + state = new CollectionAdminRequest.DeleteReplica() .setCollectionName(collection) .setShardName("shard1") .setReplica(replica) - .setAsyncId("47"); - response = deleteReplica.process(cloudClient); - assertEquals("47", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("47", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteReplica did not complete", RequestStatusState.COMPLETED, state); - CollectionAdminRequest.Delete deleteCollection = new CollectionAdminRequest.Delete() + state = new CollectionAdminRequest.Delete() .setCollectionName(collection) - .setAsyncId("48"); - response = deleteCollection.process(cloudClient); - assertEquals("48", response.getResponse().get("requestid")); - state = getRequestStateAfterCompletion("48", MAX_TIMEOUT_SECONDS, cloudClient); + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteCollection did not complete", RequestStatusState.COMPLETED, state); } + } diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java index c5d27a9a544..ab02a3e1eac 100644 --- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java +++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java @@ -161,7 +161,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase { verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[2]/name", "collection-admin-edit", 20); CollectionAdminRequest.Reload reload = new CollectionAdminRequest.Reload(); - reload.setCollectionName(cloudSolrClient.getDefaultCollection()); + reload.setCollectionName(defaultCollName); HttpSolrClient solrClient = new HttpSolrClient(baseUrl); try { 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 a7d71ca5b93..c9c8c3989df 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 @@ -21,10 +21,15 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Properties; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.SolrResponse; +import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.CollectionAdminResponse; +import org.apache.solr.client.solrj.response.RequestStatusState; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.DocCollection; @@ -37,33 +42,28 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ShardParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.util.NamedList; /** * This class is experimental and subject to change. * * @since solr 4.5 */ -public abstract class CollectionAdminRequest > extends SolrRequest { +public abstract class CollectionAdminRequest extends SolrRequest { - protected CollectionAction action = null; + protected final CollectionAction action; private static String PROPERTY_PREFIX = "property."; - protected CollectionAdminRequest setAction(CollectionAction action) { - this.action = action; - return this; + public CollectionAdminRequest(CollectionAction action) { + this("/admin/collections", action); } - public CollectionAdminRequest() { - super(METHOD.GET, "/admin/collections"); - } - - public CollectionAdminRequest(String path) { + public CollectionAdminRequest(String path, CollectionAction action) { super(METHOD.GET, path); + this.action = action; } - protected abstract Q getThis(); - @Override public SolrParams getParams() { if (action == null) { @@ -79,11 +79,6 @@ public abstract class CollectionAdminRequest > iter = props.entrySet().iterator(); while(iter.hasNext()) { @@ -94,18 +89,84 @@ public abstract class CollectionAdminRequest > extends CollectionAdminRequest { - protected String asyncId = null; + protected abstract static class AsyncCollectionAdminRequest extends CollectionAdminRequest { - public final T setAsyncId(String asyncId) { - this.asyncId = asyncId; - return getThis(); + public AsyncCollectionAdminRequest(CollectionAction action) { + super(action); } + @Override + protected CollectionAdminResponse createResponse(SolrClient client) { + return new CollectionAdminResponse(); + } + + private static String generateAsyncId() { + return UUID.randomUUID().toString(); + } + + protected String asyncId = null; + public String getAsyncId() { return asyncId; } + /** + * @deprecated Use {@link #processAsync(String, SolrClient)} or {@link #processAsync(SolrClient)} + */ + @Deprecated + public abstract AsyncCollectionAdminRequest setAsyncId(String id); + + /** + * Process this request asynchronously, generating and returning a request id + * @param client a Solr client + * @return the request id + * @see CollectionAdminRequest.RequestStatus + */ + public String processAsync(SolrClient client) throws IOException, SolrServerException { + return processAsync(generateAsyncId(), client); + } + + /** + * Process this request asynchronously, using a specified request id + * @param asyncId the request id + * @param client a Solr client + * @return the request id + */ + public String processAsync(String asyncId, SolrClient client) throws IOException, SolrServerException { + this.asyncId = asyncId; + NamedList resp = client.request(this); + if (resp.get("error") != null) { + throw new SolrServerException((String)resp.get("error")); + } + return (String) resp.get("requestid"); + } + + /** + * Send this request to a Solr server, and wait (up to a timeout) for the request to + * complete or fail + * @param client a Solr client + * @param timeoutSeconds the maximum time to wait + * @return the status of the request on completion or timeout + */ + public RequestStatusState processAndWait(SolrClient client, long timeoutSeconds) + throws SolrServerException, InterruptedException, IOException { + return processAndWait(generateAsyncId(), client, timeoutSeconds); + } + + /** + * Send this request to a Solr server, and wait (up to a timeout) for the request to + * complete or fail + * @param asyncId an id for the request + * @param client a Solr client + * @param timeoutSeconds the maximum time to wait + * @return the status of the request on completion or timeout + */ + public RequestStatusState processAndWait(String asyncId, SolrClient client, long timeoutSeconds) + throws IOException, SolrServerException, InterruptedException { + processAsync(asyncId, client); + return new RequestStatus().setRequestId(asyncId).waitFor(client, timeoutSeconds); + } + @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -116,121 +177,110 @@ public abstract class CollectionAdminRequest > extends CollectionAdminRequest { - protected String collection = null; - public T setCollectionName(String collectionName) { - this.collection = collectionName; - return getThis(); - } + protected abstract static class CollectionAdminRoleRequest extends AsyncCollectionAdminRequest { - public final String getCollectionName() { - return collection; - } - - @Override - public SolrParams getParams() { - ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - params.set(CoreAdminParams.NAME, collection); - return params; - } - } - - protected abstract static class CollectionSpecificAsyncAdminRequest> extends CollectionSpecificAdminRequest { - protected String asyncId = null; - - public final T setAsyncId(String asyncId) { - this.asyncId = asyncId; - return getThis(); - } - - public String getAsyncId() { - return asyncId; - } - - @Override - public SolrParams getParams() { - ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (asyncId != null) { - params.set(CommonAdminParams.ASYNC, asyncId); - } - return params; - } - } - - protected abstract static class CollectionShardAdminRequest > extends CollectionAdminRequest { - protected String shardName = null; - protected String collection = null; - - public T setCollectionName(String collectionName) { - this.collection = collectionName; - return getThis(); - } - - public String getCollectionName() { - return collection; - } - - public T setShardName(String shard) { - this.shardName = shard; - return getThis(); - } - - public String getShardName() { - return this.shardName; - } - - @Override - public SolrParams getParams() { - ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - params.set(CoreAdminParams.COLLECTION, collection); - params.set(CoreAdminParams.SHARD, shardName); - return params; - } - } - - protected abstract static class CollectionShardAsyncAdminRequest> extends CollectionShardAdminRequest { - protected String asyncId = null; - - public final T setAsyncId(String asyncId) { - this.asyncId = asyncId; - return getThis(); - } - - public String getAsyncId() { - return asyncId; - } - - @Override - public SolrParams getParams() { - ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (asyncId != null) { - params.set(CommonAdminParams.ASYNC, asyncId); - } - return params; - } - } - - protected abstract static class CollectionAdminRoleRequest > extends AsyncCollectionAdminRequest { protected String node; protected String role; - public T setNode(String node) { - this.node = node; - return getThis(); + + public CollectionAdminRoleRequest(CollectionAction action) { + super(action); } + @Override + public CollectionAdminRoleRequest setAsyncId(String id) { + this.asyncId = id; + return this; + } + + public abstract CollectionAdminRoleRequest setNode(String node); + public String getNode() { return this.node; } - public T setRole(String role) { - this.role = role; - return getThis(); - } + public abstract CollectionAdminRoleRequest setRole(String role); public String getRole() { return this.role; @@ -249,7 +299,8 @@ public abstract class CollectionAdminRequest { + public static class Create extends AsyncCollectionSpecificAdminRequest { + protected String configName = null; protected String createNodeSet = null; protected String routerName; @@ -263,8 +314,9 @@ public abstract class CollectionAdminRequest { + public static class Reload extends AsyncCollectionSpecificAdminRequest { + public Reload() { - action = CollectionAction.RELOAD; + super(CollectionAction.RELOAD); } @Override - public SolrParams getParams() { - ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - return params; + public Reload setCollectionName(String collection) { + this.collection = collection; + return this; } @Override - protected Reload getThis() { + public Reload setAsyncId(String id) { + this.asyncId = id; return this; } } // DELETE request - public static class Delete extends CollectionSpecificAsyncAdminRequest { + public static class Delete extends AsyncCollectionSpecificAdminRequest { public Delete() { - action = CollectionAction.DELETE; + super(CollectionAction.DELETE); } @Override - public SolrParams getParams() { - ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - return params; + public Delete setCollectionName(String collection) { + this.collection = collection; + return this; } @Override - protected Delete getThis() { + public Delete setAsyncId(String id) { + this.asyncId = id; return this; } } // CREATESHARD request - public static class CreateShard extends CollectionShardAsyncAdminRequest { + public static class CreateShard extends AsyncShardSpecificAdminRequest { + protected String nodeSet; protected Properties properties; @@ -434,9 +491,15 @@ public abstract class CollectionAdminRequest { + public static class SplitShard extends AsyncShardSpecificAdminRequest { protected String ranges; protected String splitKey; private Properties properties; public SplitShard() { - action = CollectionAction.SPLITSHARD; + super(CollectionAction.SPLITSHARD); } public SplitShard setRanges(String ranges) { this.ranges = ranges; return this; } @@ -504,6 +570,24 @@ public abstract class CollectionAdminRequest { + public static class DeleteShard extends AsyncShardSpecificAdminRequest { private Boolean deleteInstanceDir; private Boolean deleteDataDir; public DeleteShard() { - action = CollectionAction.DELETESHARD; - } - - @Override - protected DeleteShard getThis() { - return this; + super(CollectionAction.DELETESHARD); } public Boolean getDeleteInstanceDir() { @@ -557,6 +632,24 @@ public abstract class CollectionAdminRequest { + public static class ForceLeader extends ShardSpecificAdminRequest { public ForceLeader() { - action = CollectionAction.FORCELEADER; + super(CollectionAction.FORCELEADER); + } + + + @Override + public ForceLeader setCollectionName(String collection) { + this.collection = collection; + return this; } @Override - protected ForceLeader getThis() { + public ForceLeader setShardName(String shard) { + this.shard = shard; return this; } + + } + + public static class RequestStatusResponse extends CollectionAdminResponse { + + public RequestStatusState getRequestStatus() { + NamedList innerResponse = (NamedList) getResponse().get("status"); + return RequestStatusState.fromKey((String) innerResponse.get("state")); + } + } // REQUESTSTATUS request - public static class RequestStatus extends CollectionAdminRequest { - protected String requestId = null; + public static class RequestStatus extends CollectionAdminRequest { + + protected String requestId = null; public RequestStatus() { - action = CollectionAction.REQUESTSTATUS; + super(CollectionAction.REQUESTSTATUS); } public RequestStatus setRequestId(String requestId) { @@ -603,23 +715,41 @@ public abstract class CollectionAdminRequest { + public static class DeleteStatus extends CollectionAdminRequest { + protected String requestId = null; protected Boolean flush = null; public DeleteStatus() { - action = CollectionAction.DELETESTATUS; + super(CollectionAction.DELETESTATUS); } public DeleteStatus setRequestId(String requestId) { @@ -652,18 +782,20 @@ public abstract class CollectionAdminRequest { + public static class CreateAlias extends AsyncCollectionAdminRequest { + protected String aliasName; protected String aliasedCollections; public CreateAlias() { - action = CollectionAction.CREATEALIAS; + super(CollectionAction.CREATEALIAS); } /** @@ -695,6 +827,12 @@ public abstract class CollectionAdminRequest { + public static class DeleteAlias extends AsyncCollectionAdminRequest { + protected String aliasName; public DeleteAlias() { - action = CollectionAction.DELETEALIAS; + super(CollectionAction.DELETEALIAS); } public DeleteAlias setAliasName(String aliasName) { @@ -722,6 +857,12 @@ public abstract class CollectionAdminRequest { + public static class AddReplica extends AsyncCollectionAdminRequest { + + protected String collection; + protected String shard; protected String node; protected String routeKey; protected String instanceDir; @@ -744,7 +885,7 @@ public abstract class CollectionAdminRequest { + public static class DeleteReplica extends AsyncShardSpecificAdminRequest { + protected String replica; protected Boolean onlyIfDown; private Boolean deleteDataDir; @@ -832,7 +992,7 @@ public abstract class CollectionAdminRequest { + public static class ClusterProp extends CollectionAdminRequest { + private String propertyName; private String propertyValue; public ClusterProp() { - this.action = CollectionAction.CLUSTERPROP; + super(CollectionAction.CLUSTERPROP); } public ClusterProp setPropertyName(String propertyName) { @@ -934,13 +1108,16 @@ public abstract class CollectionAdminRequest { + public static class Migrate extends AsyncCollectionAdminRequest { + private String collection; private String targetCollection; private String splitKey; @@ -948,7 +1125,7 @@ public abstract class CollectionAdminRequest { + public static class AddRole extends CollectionAdminRoleRequest { + public AddRole() { - action = CollectionAction.ADDROLE; + super(CollectionAction.ADDROLE); } @Override - protected AddRole getThis() { + public AddRole setNode(String node) { + this.node = node; + return this; + } + + @Override + public AddRole setRole(String role) { + this.role = role; return this; } } // REMOVEROLE request - public static class RemoveRole extends CollectionAdminRoleRequest { + public static class RemoveRole extends CollectionAdminRoleRequest { + public RemoveRole() { - action = CollectionAction.REMOVEROLE; + super(CollectionAction.REMOVEROLE); } @Override - protected RemoveRole getThis() { + public RemoveRole setNode(String node) { + this.node = node; + return this; + } + + @Override + public RemoveRole setRole(String role) { + this.role = role; return this; } } // OVERSEERSTATUS request - public static class OverseerStatus extends AsyncCollectionAdminRequest { + public static class OverseerStatus extends AsyncCollectionAdminRequest { public OverseerStatus () { - action = CollectionAction.OVERSEERSTATUS; + super(CollectionAction.OVERSEERSTATUS); } @Override - protected OverseerStatus getThis() { + public OverseerStatus setAsyncId(String id) { + this.asyncId = id; return this; } } // CLUSTERSTATUS request - public static class ClusterStatus extends CollectionAdminRequest { + public static class ClusterStatus extends CollectionAdminRequest { protected String shardName = null; protected String collection = null; protected String routeKey = null; public ClusterStatus () { - action = CollectionAction.CLUSTERSTATUS; + super(CollectionAction.CLUSTERSTATUS); } public ClusterStatus setCollectionName(String collectionName) { @@ -1109,32 +1306,35 @@ public abstract class CollectionAdminRequest { + public static class List extends CollectionAdminRequest { public List () { - action = CollectionAction.LIST; + super(CollectionAction.LIST); } @Override - protected List getThis() { - return this; + protected CollectionAdminResponse createResponse(SolrClient client) { + return new CollectionAdminResponse(); } } // ADDREPLICAPROP request - public static class AddReplicaProp extends CollectionShardAsyncAdminRequest { + public static class AddReplicaProp extends AsyncShardSpecificAdminRequest { + private String replica; private String propertyName; private String propertyValue; private Boolean shardUnique; public AddReplicaProp() { - action = CollectionAction.ADDREPLICAPROP; + super(CollectionAction.ADDREPLICAPROP); } public String getReplica() { @@ -1173,6 +1373,24 @@ public abstract class CollectionAdminRequest { + public static class DeleteReplicaProp extends AsyncShardSpecificAdminRequest { + private String replica; private String propertyName; public DeleteReplicaProp() { - this.action = CollectionAction.DELETEREPLICAPROP; + super(CollectionAction.DELETEREPLICAPROP); } public String getReplica() { @@ -1220,6 +1435,24 @@ public abstract class CollectionAdminRequest { + public static class MigrateClusterState extends AsyncCollectionAdminRequest { + + protected String collection; public MigrateClusterState() { - this.action = CollectionAction.MIGRATESTATEFORMAT; + super(CollectionAction.MIGRATESTATEFORMAT); } - @Override - public MigrateClusterState setShardName(String shard) { - throw new UnsupportedOperationException(); - } - - @Override - public String getShardName() { - throw new UnsupportedOperationException(); - } - - @Override - protected MigrateClusterState getThis() { + public MigrateClusterState setCollectionName(String collection) { + this.collection = collection; return this; } + + @Override + public MigrateClusterState setAsyncId(String id) { + this.asyncId = id; + return this; + } + + @Override + public SolrParams getParams() { + ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); + if (collection == null) + throw new IllegalArgumentException("You must call setCollection() on this request"); + params.set(CoreAdminParams.COLLECTION, collection); + return params; + } } // BALANCESHARDUNIQUE request - public static class BalanceShardUnique extends AsyncCollectionAdminRequest { + public static class BalanceShardUnique extends AsyncCollectionAdminRequest { + protected String collection; protected String propertyName; protected Boolean onlyActiveNodes; protected Boolean shardUnique; public BalanceShardUnique() { - this.action = CollectionAction.BALANCESHARDUNIQUE; + super(CollectionAction.BALANCESHARDUNIQUE); } public String getPropertyName() { @@ -1304,21 +1542,24 @@ public abstract class CollectionAdminRequest