From 71411df0cfec385fbd0fcd0f0291c6a06c05a428 Mon Sep 17 00:00:00 2001 From: Karl Wright Date: Wed, 31 May 2017 07:55:53 -0400 Subject: [PATCH 01/11] LUCENE-7853: Add methods for people to use who know their polygon's characteristics --- .../spatial3d/geom/GeoPolygonFactory.java | 63 +++++++++++++++++++ .../lucene/spatial3d/geom/GeoPolygonTest.java | 63 +++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java index 97bc230bb5b..4c1850ec06a 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java @@ -49,6 +49,34 @@ public class GeoPolygonFactory { return makeGeoPolygon(planetModel, pointList, null); } + /** Create a GeoConcavePolygon using the specified points. The polygon must have + * a maximum extent larger than PI. The siding of the polygon is chosen so that any + * adjacent point to a segment provides an exterior measurement and therefore, + * the polygon is a truly concave polygon. Note that this method should only be used when there is certainty + * that we are dealing with a concave polygon, e.g. the polygon has been serialized. + * If there is not such certainty, please refer to @{@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List)}. + * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. + * @return a GeoConcavePolygon corresponding to what was specified. + */ + public static GeoConcavePolygon makeGeoConcavePolygon(final PlanetModel planetModel, + final List pointList) { + return new GeoConcavePolygon(planetModel, pointList); + } + + /** Create a GeoConvexPolygon using the specified points. The polygon must have + * a maximum extent no larger than PI. The siding of the polygon is chosen so that any adjacent + * point to a segment provides an interior measurement and therefore + * the polygon is a truly convex polygon. Note that this method should only be used when + * there is certainty that we are dealing with a convex polygon, e.g. the polygon has been serialized. + * If there is not such certainty, please refer to @{@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List)}. + * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. + * @return a GeoConvexPolygon corresponding to what was specified. + */ + public static GeoConvexPolygon makeGeoConvexPolygon(final PlanetModel planetModel, + final List pointList) { + return new GeoConvexPolygon(planetModel, pointList); + } + /** Create a GeoPolygon using the specified points and holes, using order to determine * siding of the polygon. Much like ESRI, this method uses clockwise to indicate the space * on the same side of the shape as being inside, and counter-clockwise to indicate the @@ -66,6 +94,41 @@ public class GeoPolygonFactory { final List holes) { return makeGeoPolygon(planetModel, pointList, holes, 0.0); } + + + /** Create a GeoConcavePolygon using the specified points and holes. The polygon must have + * a maximum extent larger than PI. The siding of the polygon is chosen so that any adjacent + * point to a segment provides an exterior measurement and therefore + * the polygon is a truly concave polygon. Note that this method should only be used when + * there is certainty that we are dealing with a concave polygon, e.g. the polygon has been serialized. + * If there is not such certainty, please refer to {@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List, List)}. + * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. + * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside + * each hole as being "in set". Null == none. + * @return a GeoConcavePolygon corresponding to what was specified. + */ + public static GeoConcavePolygon makeGeoConcavePolygon(final PlanetModel planetModel, + final List pointList, + final List holes) { + return new GeoConcavePolygon(planetModel,pointList, holes); + } + + /** Create a GeoConvexPolygon using the specified points and holes. The polygon must have + * a maximum extent no larger than PI. The siding of the polygon is chosen so that any adjacent + * point to a segment provides an interior measurement and therefore + * the polygon is a truly convex polygon. Note that this method should only be used when + * there is certainty that we are dealing with a convex polygon, e.g. the polygon has been serialized. + * If there is not such certainty, please refer to {@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List, List)}. + * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. + * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside + * each hole as being "in set". Null == none. + * @return a GeoConvexPolygon corresponding to what was specified. + */ + public static GeoConvexPolygon makeGeoConvexPolygon(final PlanetModel planetModel, + final List pointList, + final List holes) { + return new GeoConvexPolygon(planetModel,pointList, holes); + } /** Create a GeoPolygon using the specified points and holes, using order to determine * siding of the polygon. Much like ESRI, this method uses clockwise to indicate the space diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java index 8527e99afc4..f3ac52bb352 100755 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java @@ -19,6 +19,7 @@ package org.apache.lucene.spatial3d.geom; import java.util.ArrayList; import java.util.List; import java.util.BitSet; +import java.util.Collections; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -966,5 +967,67 @@ shape: assertTrue(solid.isWithin(point)); } + + @Test + public void testConcavePolygon() { + ArrayList points = new ArrayList<>(); + points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4)); + GeoPolygon polygon = (GeoPolygon)((GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points)).shapes.get(0); + GeoPolygon polygonConcave = GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE,points); + assertEquals(polygon,polygonConcave); + } + + @Test + public void testConcavePolygonWithHole() { + ArrayList points = new ArrayList<>(); + points.add(new GeoPoint(PlanetModel.SPHERE, -1.1, -1.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 1.0, -1.6)); + points.add(new GeoPoint(PlanetModel.SPHERE, 1.1, -1.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 1.0, -1.4)); + ArrayList hole_points = new ArrayList<>(); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4)); + GeoPolygon hole = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE,hole_points); + + GeoPolygon polygon = (GeoPolygon)((GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,Collections.singletonList(hole))).shapes.get(0); + GeoPolygon polygon2 = GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE,points,Collections.singletonList(hole)); + assertEquals(polygon,polygon2); + } + + @Test + public void testConvexPolygon() { + ArrayList points = new ArrayList<>(); + points.add(new GeoPoint(PlanetModel.SPHERE, 0, 0)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, 0.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.5, 0.5)); + points.add(new GeoPoint(PlanetModel.SPHERE, 0.5, 0)); + GeoPolygon polygon = (GeoPolygon)((GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points)).shapes.get(0); + GeoPolygon polygon2 = GeoPolygonFactory.makeGeoConvexPolygon(PlanetModel.SPHERE,points); + assertEquals(polygon,polygon2); + } + + @Test + public void testConvexPolygonWithHole() { + ArrayList points = new ArrayList<>(); + points.add(new GeoPoint(PlanetModel.SPHERE, -1, -1)); + points.add(new GeoPoint(PlanetModel.SPHERE, -1, 1)); + points.add(new GeoPoint(PlanetModel.SPHERE, 1, 1)); + points.add(new GeoPoint(PlanetModel.SPHERE, 1, -1)); + ArrayList hole_points = new ArrayList<>(); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5)); + hole_points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4)); + GeoPolygon hole = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE,hole_points); + + GeoPolygon polygon = (GeoPolygon)((GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,Collections.singletonList(hole))).shapes.get(0); + GeoPolygon polygon2 = GeoPolygonFactory.makeGeoConvexPolygon(PlanetModel.SPHERE,points,Collections.singletonList(hole)); + assertEquals(polygon,polygon2); + } } From 2d6edc69b365b8bcc0450b647b2facfac6e777c7 Mon Sep 17 00:00:00 2001 From: Cassandra Targett Date: Wed, 31 May 2017 09:28:47 -0500 Subject: [PATCH 02/11] Ref Guide: finish bin/solr auth docs for SOLR-8440 --- .../src/solr-control-script-reference.adoc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/solr/solr-ref-guide/src/solr-control-script-reference.adoc b/solr/solr-ref-guide/src/solr-control-script-reference.adoc index d5fc5c8dd98..fd27d0a9169 100644 --- a/solr/solr-ref-guide/src/solr-control-script-reference.adoc +++ b/solr/solr-ref-guide/src/solr-control-script-reference.adoc @@ -425,7 +425,7 @@ This option is useful if you are running multiple standalone Solr instances on t The `bin/solr` script allows enabling or disabling Basic Authentication, allowing you to configure authentication from the command line. -Currently, this script only enables Basic Authentication. +Currently, this script only enables Basic Authentication, and is only available when using SolrCloud mode. === Enabling Basic Authentication @@ -435,7 +435,7 @@ TIP: For more information about Solr's authentication plugins, see the section < The `bin/solr auth enable` command makes several changes to enable Basic Authentication: -* Creates a `security.json` file and, if using SolrCloud, uploads it to ZooKeeper. The `security.json` file will look similar to: +* Creates a `security.json` file and uploads it to ZooKeeper. The `security.json` file will look similar to: + [source,json] ---- @@ -484,15 +484,14 @@ When *true*, blocks all unauthenticated users from accessing Solr. This defaults `-updateIncludeFileOnly`:: When *true*, only the settings in `bin/solr.in.sh` or `bin\solr.in.cmd` will be updated, and `security.json` will not be created. -// TODO 6.6 clarify when this is required `-z`:: -Defines the ZooKeeper connect string. +Defines the ZooKeeper connect string. This is useful if you want to enable authentication before all your Solr nodes have come up. `-d`:: -Defines the Solr server directory, by default `$SOLR_HOME/server`. It is not common to need to override the default. +Defines the Solr server directory, by default `$SOLR_HOME/server`. It is not common to need to override the default, and is only needed if you have customized the `$SOLR_HOME` directory path. `-s`:: -Defines the location of `solr.solr.home`, which by default is `server/solr`. If you have multiple instances of Solr on the same host, you likely need to define this. +Defines the location of `solr.solr.home`, which by default is `server/solr`. If you have multiple instances of Solr on the same host, or if you have customized the `$SOLR_HOME` directory path, you likely need to define this. === Disabling Basic Authentication From 55e37cdd3deb3d2934690aa10b02a0aaef7780ff Mon Sep 17 00:00:00 2001 From: Steve Rowe Date: Wed, 31 May 2017 11:26:28 -0400 Subject: [PATCH 03/11] SOLR-9596: Ref guide: document SimpleTextCodecFactory --- solr/solr-ref-guide/src/codec-factory.adoc | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/solr/solr-ref-guide/src/codec-factory.adoc b/solr/solr-ref-guide/src/codec-factory.adoc index bb5f0e09986..88bc0831946 100644 --- a/solr/solr-ref-guide/src/codec-factory.adoc +++ b/solr/solr-ref-guide/src/codec-factory.adoc @@ -20,7 +20,16 @@ A `codecFactory` can be specified in `solrconfig.xml` to determine which Lucene {lucene-javadocs}/core/org/apache/lucene/codecs/Codec.html[`Codec`] is used when writing the index to disk. -If not specified, Lucene's default codec is implicitly used, but a {solr-javadocs}/solr-core/org/apache/solr/core/SchemaCodecFactory.html[`solr.SchemaCodecFactory`] is also available which supports 2 key features: +If not specified, Lucene's default codec is implicitly used. + +There are two alternatives to Lucene's default codec: + +. {solr-javadocs}/solr-core/org/apache/solr/core/SchemaCodecFactory.html[`solr.SchemaCodecFactory`] +. {solr-javadocs}/solr-core/org/apache/solr/core/SimpleTextCodecFactory.html[`solr.SimpleTextCodecFactory`] + +=== solr.SchemaCodecFactory + +`solr.SchemaCodecFactory` supports 2 key features: * Schema based per-fieldtype configuration for `docValuesFormat` and `postingsFormat` - see the <> section for more details. * A `compressionMode` option: @@ -35,3 +44,16 @@ Example: BEST_COMPRESSION ---- + +=== solr.SimpleTextCodecFactory + +This factory for Lucene's `SimpleTextCodec` produces a plain text human-readable index format. + +CAUTION: *FOR RECREATIONAL USE ONLY*. This codec should never be used in production. `SimpleTextCodec` is relatively slow and takes up a large amount of disk space. Its use should be limited to educational and debugging purposes. + +Example: + +[source,xml] +---- + +---- From ee33f38bd1b4c039dc0d054ccf0eb2904fc9ea92 Mon Sep 17 00:00:00 2001 From: Chris Hostetter Date: Wed, 31 May 2017 09:49:56 -0700 Subject: [PATCH 04/11] SOLR-10757: delete/refactor/cleanup CollectionAdminRequest deprecations --- solr/CHANGES.txt | 2 + .../core/snapshots/SolrSnapshotsTool.java | 7 +- .../AbstractCloudBackupRestoreTestCase.java | 11 +- .../CollectionsAPIAsyncDistributedZkTest.java | 62 +- .../solr/cloud/CollectionsAPISolrJTest.java | 12 +- ...ncurrentDeleteAndCreateCollectionTest.java | 12 +- .../apache/solr/cloud/DeleteStatusTest.java | 23 - .../apache/solr/cloud/ForceLeaderTest.java | 25 +- .../cloud/FullSolrCloudDistribCmdsTest.java | 16 +- .../apache/solr/cloud/HttpPartitionTest.java | 36 +- .../LeaderFailoverAfterPartitionTest.java | 10 +- .../LeaderInitiatedRecoveryOnCommitTest.java | 19 +- .../solr/cloud/MultiThreadedOCPTest.java | 63 +- .../apache/solr/cloud/ReplaceNodeTest.java | 4 +- .../solr/cloud/ReplicationFactorTest.java | 4 +- .../apache/solr/cloud/RollingRestartTest.java | 2 +- .../org/apache/solr/cloud/ShardSplitTest.java | 8 +- .../SharedFSAutoReplicaFailoverTest.java | 24 +- .../SimpleCollectionCreateDeleteTest.java | 13 +- .../apache/solr/cloud/TestCollectionAPI.java | 24 +- .../cloud/TestRandomRequestDistribution.java | 15 +- .../solr/cloud/TestRequestForwarding.java | 6 +- .../cloud/TestSolrCloudWithKerberosAlt.java | 9 +- .../TestSolrCloudWithSecureImpersonation.java | 6 +- .../apache/solr/handler/TestBlobHandler.java | 10 +- .../solr/search/stats/TestDistribIDF.java | 13 +- .../solrj/request/CollectionAdminRequest.java | 844 ++---------------- ...lectionAdminRequestRequiredParamsTest.java | 137 +-- .../request/TestCollectionAdminRequest.java | 84 +- .../cloud/AbstractFullDistribZkTestBase.java | 23 +- 30 files changed, 316 insertions(+), 1208 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3661037ca77..d78f991468c 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -198,6 +198,8 @@ Other Changes * SOLR-10755: delete/refactor many solrj deprecations (hossman) +* SOLR-10757: delete/refactor/cleanup CollectionAdminRequest deprecations (hossman) + ================== 6.7.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. diff --git a/solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java b/solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java index 935ef638f8c..76e5bebe2eb 100644 --- a/solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java +++ b/solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java @@ -301,11 +301,8 @@ public class SolrSnapshotsTool implements Closeable { if (backupRepo.isPresent()) { backup.setRepositoryName(backupRepo.get()); } - if (asyncReqId.isPresent()) { - backup.setAsyncId(asyncReqId.get()); - } - CollectionAdminResponse resp = backup.process(solrClient); - Preconditions.checkState(resp.getStatus() == 0, "The request failed. The status code is " + resp.getStatus()); + // if asyncId is null, processAsync will block and throw an Exception with any error + backup.processAsync(asyncReqId.orElse(null), solrClient); } catch (Exception e) { log.error("Failed to backup collection meta-data for collection " + collectionName, e); System.out.println("Failed to backup collection meta-data for collection " + collectionName diff --git a/solr/core/src/test/org/apache/solr/cloud/AbstractCloudBackupRestoreTestCase.java b/solr/core/src/test/org/apache/solr/cloud/AbstractCloudBackupRestoreTestCase.java index f86322d779d..526a8dfab65 100644 --- a/solr/core/src/test/org/apache/solr/cloud/AbstractCloudBackupRestoreTestCase.java +++ b/solr/core/src/test/org/apache/solr/cloud/AbstractCloudBackupRestoreTestCase.java @@ -87,8 +87,12 @@ public abstract class AbstractCloudBackupRestoreTestCase extends SolrCloudTestCa int replFactor = TestUtil.nextInt(random(), 1, 2); int numTlogReplicas = TestUtil.nextInt(random(), 0, 1); int numPullReplicas = TestUtil.nextInt(random(), 0, 1); - CollectionAdminRequest.Create create = - CollectionAdminRequest.createCollection(getCollectionName(), "conf1", NUM_SHARDS, replFactor, numTlogReplicas, numPullReplicas); + + CollectionAdminRequest.Create create = isImplicit ? + // NOTE: use shard list with same # of shards as NUM_SHARDS; we assume this later + CollectionAdminRequest.createCollectionWithImplicitRouter(getCollectionName(), "conf1", "shard1,shard2", replFactor, numTlogReplicas, numPullReplicas) : + CollectionAdminRequest.createCollection(getCollectionName(), "conf1", NUM_SHARDS, replFactor, numTlogReplicas, numPullReplicas); + if (NUM_SHARDS * (replFactor + numTlogReplicas + numPullReplicas) > cluster.getJettySolrRunners().size() || random().nextBoolean()) { create.setMaxShardsPerNode((int)Math.ceil(NUM_SHARDS * (replFactor + numTlogReplicas + numPullReplicas) / cluster.getJettySolrRunners().size()));//just to assert it survives the restoration if (doSplitShardOperation) { @@ -102,9 +106,6 @@ public abstract class AbstractCloudBackupRestoreTestCase extends SolrCloudTestCa coreProps.put("customKey", "customValue");//just to assert it survives the restoration create.setProperties(coreProps); if (isImplicit) { //implicit router - create.setRouterName(ImplicitDocRouter.NAME); - create.setNumShards(null);//erase it. TODO suggest a new createCollectionWithImplicitRouter method - create.setShards("shard1,shard2"); // however still same number as NUM_SHARDS; we assume this later create.setRouterField("shard_s"); } else {//composite id router if (random().nextBoolean()) { 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 30c3c9e40d4..1474b5c52cd 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java @@ -24,8 +24,6 @@ import org.apache.lucene.util.TestUtil; import org.apache.solr.client.solrj.SolrQuery; 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.common.SolrException; import org.apache.solr.common.SolrInputDocument; @@ -54,29 +52,19 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { final CloudSolrClient client = cluster.getSolrClient(); - RequestStatusState state = new Create() - .setCollectionName("testasynccollectioncreation") - .setNumShards(1) - .setReplicationFactor(1) - .setConfigName("conf1") + RequestStatusState state = CollectionAdminRequest.createCollection("testasynccollectioncreation","conf1",1,1) .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state); - state = new Create() - .setCollectionName("testasynccollectioncreation") - .setNumShards(1) - .setConfigName("conf1") + state = CollectionAdminRequest.createCollection("testasynccollectioncreation","conf1",1,1) .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); + state = CollectionAdminRequest.addReplicaToShard("testasynccollectioncreation", "shard1") + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("Add replica did not complete", RequestStatusState.COMPLETED, state); - state = new SplitShard() - .setCollectionName("testasynccollectioncreation") + state = CollectionAdminRequest.splitShard("testasynccollectioncreation") .setShardName("shard1") .processAndWait(client, MAX_TIMEOUT_SECONDS * 2); assertEquals("Shard split did not complete. Last recorded state: " + state, RequestStatusState.COMPLETED, state); @@ -89,12 +77,9 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { final String collection = "testAsyncOperations"; final CloudSolrClient client = cluster.getSolrClient(); - RequestStatusState state = new Create() - .setCollectionName(collection) - .setNumShards(1) + RequestStatusState state = CollectionAdminRequest.createCollection(collection,"conf1",1,1) .setRouterName("implicit") .setShards("shard1") - .setConfigName("conf1") .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state); @@ -114,14 +99,11 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { query.set("shards", "shard1"); assertEquals(numDocs, client.query(collection, query).getResults().getNumFound()); - state = new CollectionAdminRequest.Reload() - .setCollectionName(collection) + state = CollectionAdminRequest.reloadCollection(collection) .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("ReloadCollection did not complete", RequestStatusState.COMPLETED, state); - state = new CollectionAdminRequest.CreateShard() - .setCollectionName(collection) - .setShardName("shard2") + state = CollectionAdminRequest.createShard(collection,"shard2") .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateShard did not complete", RequestStatusState.COMPLETED, state); @@ -135,16 +117,11 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { query.set("shards", "shard2"); assertEquals(1, client.query(collection, query).getResults().getNumFound()); - state = new CollectionAdminRequest.DeleteShard() - .setCollectionName(collection) - .setShardName("shard2") - .processAndWait(client, MAX_TIMEOUT_SECONDS); + state = CollectionAdminRequest.deleteShard(collection,"shard2").processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteShard did not complete", RequestStatusState.COMPLETED, state); - state = new CollectionAdminRequest.AddReplica() - .setCollectionName(collection) - .setShardName("shard1") - .processAndWait(client, MAX_TIMEOUT_SECONDS); + state = CollectionAdminRequest.addReplicaToShard(collection, "shard1") + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("AddReplica did not complete", RequestStatusState.COMPLETED, state); //cloudClient watch might take a couple of seconds to reflect it @@ -157,9 +134,7 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { Thread.sleep(100); } - state = new CollectionAdminRequest.CreateAlias() - .setAliasName("myalias") - .setAliasedCollections(collection) + state = CollectionAdminRequest.createAlias("myalias",collection) .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("CreateAlias did not complete", RequestStatusState.COMPLETED, state); @@ -167,8 +142,7 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { query.set("shards", "shard1"); assertEquals(numDocs, client.query("myalias", query).getResults().getNumFound()); - state = new CollectionAdminRequest.DeleteAlias() - .setAliasName("myalias") + state = CollectionAdminRequest.deleteAlias("myalias") .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteAlias did not complete", RequestStatusState.COMPLETED, state); @@ -191,15 +165,11 @@ public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase { shard1 = client.getZkStateReader().getClusterState().getSlice(collection, "shard1"); String replicaName = shard1.getReplicas().iterator().next().getName(); - state = new CollectionAdminRequest.DeleteReplica() - .setCollectionName(collection) - .setShardName("shard1") - .setReplica(replicaName) - .processAndWait(client, MAX_TIMEOUT_SECONDS); + state = CollectionAdminRequest.deleteReplica(collection, "shard1", replicaName) + .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteReplica did not complete", RequestStatusState.COMPLETED, state); - state = new CollectionAdminRequest.Delete() - .setCollectionName(collection) + state = CollectionAdminRequest.deleteCollection(collection) .processAndWait(client, MAX_TIMEOUT_SECONDS); assertSame("DeleteCollection did not complete", RequestStatusState.COMPLETED, state); } diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java index 643660bc293..861bdcc53f1 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java @@ -267,17 +267,21 @@ public class CollectionsAPISolrJTest extends SolrCloudTestCase { @Test public void testClusterProp() throws InterruptedException, IOException, SolrServerException { + // sanity check our expected default + final ClusterProperties props = new ClusterProperties(zkClient()); + assertEquals("Expecting prop to default to unset, test needs upated", + props.getClusterProperty(ZkStateReader.LEGACY_CLOUD, null), null); + CollectionAdminResponse response = CollectionAdminRequest.setClusterProperty(ZkStateReader.LEGACY_CLOUD, "false") - .process(cluster.getSolrClient()); + .process(cluster.getSolrClient()); assertEquals(0, response.getStatus()); - ClusterProperties props = new ClusterProperties(zkClient()); - assertEquals("Cluster property was not set", props.getClusterProperty(ZkStateReader.LEGACY_CLOUD, "true"), "false"); + assertEquals("Cluster property was not set", props.getClusterProperty(ZkStateReader.LEGACY_CLOUD, null), "false"); // Unset ClusterProp that we set. CollectionAdminRequest.setClusterProperty(ZkStateReader.LEGACY_CLOUD, null).process(cluster.getSolrClient()); - assertEquals("Cluster property was not unset", props.getClusterProperty(ZkStateReader.LEGACY_CLOUD, "true"), "true"); + assertEquals("Cluster property was not unset", props.getClusterProperty(ZkStateReader.LEGACY_CLOUD, null), null); } diff --git a/solr/core/src/test/org/apache/solr/cloud/ConcurrentDeleteAndCreateCollectionTest.java b/solr/core/src/test/org/apache/solr/cloud/ConcurrentDeleteAndCreateCollectionTest.java index 151230dc69b..bc3b9c50621 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ConcurrentDeleteAndCreateCollectionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ConcurrentDeleteAndCreateCollectionTest.java @@ -164,11 +164,8 @@ public class ConcurrentDeleteAndCreateCollectionTest extends SolrTestCaseJ4 { private void createCollection() { try { - final CollectionAdminResponse response = new CollectionAdminRequest.Create() - .setCollectionName(collectionName) - .setNumShards(1) - .setReplicationFactor(1) - .setConfigName(configName).process(solrClient); + final CollectionAdminResponse response = CollectionAdminRequest.createCollection(collectionName,configName,1,1) + .process(solrClient); if (response.getStatus() != 0) { addFailure(new RuntimeException("failed to create collection " + collectionName)); } @@ -180,9 +177,8 @@ public class ConcurrentDeleteAndCreateCollectionTest extends SolrTestCaseJ4 { private void deleteCollection() { try { - final CollectionAdminRequest.Delete deleteCollectionRequest = new CollectionAdminRequest.Delete() - .setCollectionName(collectionName); - + final CollectionAdminRequest.Delete deleteCollectionRequest + = CollectionAdminRequest.deleteCollection(collectionName); final CollectionAdminResponse response = deleteCollectionRequest.process(solrClient); if (response.getStatus() != 0) { addFailure(new RuntimeException("failed to delete collection " + collectionName)); diff --git a/solr/core/src/test/org/apache/solr/cloud/DeleteStatusTest.java b/solr/core/src/test/org/apache/solr/cloud/DeleteStatusTest.java index 3b8e014c0a7..bd14ef73a76 100644 --- a/solr/core/src/test/org/apache/solr/cloud/DeleteStatusTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/DeleteStatusTest.java @@ -120,27 +120,4 @@ public class DeleteStatusTest extends SolrCloudTestCase { CollectionAdminRequest.requestStatus(id2).process(client).getRequestStatus()); } - - @Test - @SuppressWarnings("deprecation") - public void testDeprecatedConstructorValidation() throws Exception { - - final CloudSolrClient client = cluster.getSolrClient(); - - try { - new CollectionAdminRequest.DeleteStatus().process(client); - fail("delete status should have failed"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("Either requestid or flush parameter must be specified.")); - } - - try { - new CollectionAdminRequest.DeleteStatus().setFlush(true) - .setRequestId("foo") - .process(client); - fail("delete status should have failed"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("Both requestid and flush parameters can not be specified together.")); - } - } } diff --git a/solr/core/src/test/org/apache/solr/cloud/ForceLeaderTest.java b/solr/core/src/test/org/apache/solr/cloud/ForceLeaderTest.java index 8f35c888a3c..b57dcb79003 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ForceLeaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ForceLeaderTest.java @@ -152,14 +152,7 @@ public class ForceLeaderTest extends HttpPartitionTest { } finally { log.info("Cleaning up after the test."); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } } @@ -206,15 +199,7 @@ public class ForceLeaderTest extends HttpPartitionTest { } } finally { log.info("Cleaning up after the test."); - // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } } @@ -431,10 +416,8 @@ public class ForceLeaderTest extends HttpPartitionTest { } private void doForceLeader(SolrClient client, String collectionName, String shard) throws IOException, SolrServerException { - CollectionAdminRequest.ForceLeader forceLeader = new CollectionAdminRequest.ForceLeader(); - forceLeader.setCollectionName(collectionName); - forceLeader.setShardName(shard); - client.request(forceLeader); + CollectionAdminRequest.ForceLeader forceLeader = CollectionAdminRequest.forceLeaderElection(collectionName, shard); + client.request(forceLeader); } protected int getNumberOfActiveReplicas(ClusterState clusterState, String collection, String sliceId) { diff --git a/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java b/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java index 7f3ab9691c4..9355c436851 100644 --- a/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java @@ -157,13 +157,9 @@ public class FullSolrCloudDistribCmdsTest extends AbstractFullDistribZkTestBase CollectionAdminResponse response; Map> coresStatus; - CollectionAdminRequest.Create createCollectionRequest = new CollectionAdminRequest.Create() - .setCollectionName("implicit_collection_without_routerfield") - .setRouterName("implicit") - .setNumShards(2) - .setShards("shard1,shard2") - .setReplicationFactor(2) - .setConfigName("conf1"); + CollectionAdminRequest.Create createCollectionRequest + = CollectionAdminRequest.createCollectionWithImplicitRouter("implicit_collection_without_routerfield", + "conf1","shard1,shard2",2); response = createCollectionRequest.process(server); assertEquals(0, response.getStatus()); @@ -285,14 +281,10 @@ public class FullSolrCloudDistribCmdsTest extends AbstractFullDistribZkTestBase CollectionAdminResponse response; Map> coresStatus; - response = new CollectionAdminRequest.Create() - .setCollectionName("compositeid_collection_with_routerfield") + response = CollectionAdminRequest.createCollection("compositeid_collection_with_routerfield","conf1",2,2) .setRouterName("compositeId") .setRouterField("routefield_s") - .setNumShards(2) .setShards("shard1,shard2") - .setReplicationFactor(2) - .setConfigName("conf1") .process(server); assertEquals(0, response.getStatus()); diff --git a/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java b/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java index 2cc1c3053fa..6c7de885e58 100644 --- a/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java @@ -37,7 +37,6 @@ 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.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.common.SolrException; @@ -199,13 +198,7 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase { zkClient.delete(znodePath, -1, false); // try to clean up - try { - new CollectionAdminRequest.Delete() - .setCollectionName(testCollectionName).process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } protected void testMinRf() throws Exception { @@ -387,13 +380,7 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase { log.info("testRf2 succeeded ... deleting the "+testCollectionName+" collection"); // try to clean up - try { - new CollectionAdminRequest.Delete() - .setCollectionName(testCollectionName).process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } protected void testRf3() throws Exception { @@ -443,14 +430,7 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase { log.info("testRf3 succeeded ... deleting the "+testCollectionName+" collection"); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } // test inspired by SOLR-6511 @@ -534,14 +514,7 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase { log.info("testLeaderZkSessionLoss succeeded ... deleting the "+testCollectionName+" collection"); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } protected List getActiveOrRecoveringReplicas(String testCollectionName, String shardId) throws Exception { @@ -693,4 +666,5 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase { log.info("Took {} ms to see replicas [{}] become active.", timer.getTime(), replicasToCheck); } + } diff --git a/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java b/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java index f172267281d..975459dcef9 100644 --- a/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java @@ -20,7 +20,6 @@ import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.SolrTestCaseJ4.SuppressSSL; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrClient; -import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.cloud.Replica; import org.junit.Test; @@ -184,13 +183,6 @@ public class LeaderFailoverAfterPartitionTest extends HttpPartitionTest { assertDocsExistInAllReplicas(participatingReplicas, testCollectionName, 1, 6); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); } } diff --git a/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java b/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java index f3965acfccd..f900d3a673d 100644 --- a/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java @@ -19,7 +19,6 @@ package org.apache.solr.cloud; import org.apache.http.NoHttpResponseException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrClient; -import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.Replica; import org.apache.solr.util.RTimer; @@ -96,14 +95,7 @@ public class LeaderInitiatedRecoveryOnCommitTest extends BasicDistributedZkTest Thread.sleep(sleepMsBeforeHealPartition); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); log.info("multiShardTest completed OK"); } @@ -144,14 +136,7 @@ public class LeaderInitiatedRecoveryOnCommitTest extends BasicDistributedZkTest Thread.sleep(sleepMsBeforeHealPartition); // try to clean up - try { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); - } catch (Exception e) { - // don't fail the test - log.warn("Could not delete collection {} after test completed", testCollectionName); - } + attemptCollectionDelete(cloudClient, testCollectionName); log.info("oneShardTest completed OK"); } diff --git a/solr/core/src/test/org/apache/solr/cloud/MultiThreadedOCPTest.java b/solr/core/src/test/org/apache/solr/cloud/MultiThreadedOCPTest.java index c0f29d24ee1..537dbba86e2 100644 --- a/solr/core/src/test/org/apache/solr/cloud/MultiThreadedOCPTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/MultiThreadedOCPTest.java @@ -24,6 +24,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; +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.request.QueryRequest; @@ -31,7 +32,6 @@ import org.apache.solr.client.solrj.response.CollectionAdminResponse; import org.apache.solr.client.solrj.response.RequestStatusState; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.Utils; import org.junit.Test; import org.slf4j.Logger; @@ -116,12 +116,7 @@ public class MultiThreadedOCPTest extends AbstractFullDistribZkTestBase { private void testParallelCollectionAPICalls() throws IOException, SolrServerException { try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { for(int i = 1 ; i <= NUM_COLLECTIONS ; i++) { - new Create() - .setCollectionName("ocptest" + i) - .setNumShards(4) - .setConfigName("conf1") - .setAsyncId(String.valueOf(i)) - .process(client); + CollectionAdminRequest.createCollection("ocptest" + i,"conf1",4,1).processAsync(String.valueOf(i), client); } boolean pass = false; @@ -158,12 +153,8 @@ public class MultiThreadedOCPTest extends AbstractFullDistribZkTestBase { "/overseer/collection-queue-work", new Overseer.Stats()); try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { - Create createCollectionRequest = new Create() - .setCollectionName("ocptest_shardsplit") - .setNumShards(4) - .setConfigName("conf1") - .setAsyncId("1000"); - createCollectionRequest.process(client); + Create createCollectionRequest = CollectionAdminRequest.createCollection("ocptest_shardsplit","conf1",4,1); + createCollectionRequest.processAsync("1000",client); distributedQueue.offer(Utils.toJSON(Utils.makeMap( "collection", "ocptest_shardsplit", @@ -215,36 +206,21 @@ public class MultiThreadedOCPTest extends AbstractFullDistribZkTestBase { private void testDeduplicationOfSubmittedTasks() throws IOException, SolrServerException { try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { - new Create() - .setCollectionName("ocptest_shardsplit2") - .setNumShards(4) - .setConfigName("conf1") - .setAsyncId("3000") - .process(client); + CollectionAdminRequest.createCollection("ocptest_shardsplit2","conf1",4,1).processAsync("3000",client); - SplitShard splitShardRequest = new SplitShard() - .setCollectionName("ocptest_shardsplit2") - .setShardName(SHARD1) - .setAsyncId("3001"); - splitShardRequest.process(client); - - splitShardRequest = new SplitShard() - .setCollectionName("ocptest_shardsplit2") - .setShardName(SHARD2) - .setAsyncId("3002"); - splitShardRequest.process(client); + SplitShard splitShardRequest = CollectionAdminRequest.splitShard("ocptest_shardsplit2").setShardName(SHARD1); + splitShardRequest.processAsync("3001",client); + + splitShardRequest = CollectionAdminRequest.splitShard("ocptest_shardsplit2").setShardName(SHARD2); + splitShardRequest.processAsync("3002",client); // Now submit another task with the same id. At this time, hopefully the previous 3002 should still be in the queue. - splitShardRequest = new SplitShard() - .setCollectionName("ocptest_shardsplit2") - .setShardName(SHARD1) - .setAsyncId("3002"); - CollectionAdminResponse response = splitShardRequest.process(client); - - NamedList r = response.getResponse(); - assertEquals("Duplicate request was supposed to exist but wasn't found. De-duplication of submitted task failed.", - "Task with the same requestid already exists.", r.get("error")); - + expectThrows(SolrServerException.class, () -> { + CollectionAdminRequest.splitShard("ocptest_shardsplit2").setShardName(SHARD1).processAsync("3002",client); + // more helpful assertion failure + fail("Duplicate request was supposed to exist but wasn't found. De-duplication of submitted task failed."); + }); + for (int i = 3001; i <= 3002; i++) { final RequestStatusState state = getRequestStateAfterCompletion(i + "", REQUEST_STATUS_TIMEOUT, client); assertSame("Task " + i + " did not complete, final state: " + state, RequestStatusState.COMPLETED, state); @@ -271,11 +247,8 @@ public class MultiThreadedOCPTest extends AbstractFullDistribZkTestBase { indexThread.start(); try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { - SplitShard splitShardRequest = new SplitShard() - .setCollectionName("collection1") - .setShardName(SHARD1) - .setAsyncId("2000"); - splitShardRequest.process(client); + SplitShard splitShardRequest = CollectionAdminRequest.splitShard("collection1").setShardName(SHARD1); + splitShardRequest.processAsync("2000",client); RequestStatusState state = getRequestState("2000", client); while (state == RequestStatusState.SUBMITTED) { diff --git a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java index e1af6075b64..ecfd3eedc21 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java @@ -65,7 +65,9 @@ public class ReplaceNodeTest extends SolrCloudTestCase { String emptyNode = l.remove(0); String node2bdecommissioned = l.get(0); CollectionAdminRequest.Create create; - create = pickRandom(CollectionAdminRequest.createCollection(coll, "conf1", 5, 2), + // NOTE: always using the createCollection that takes in 'int' for all types of replicas, so we never + // have to worry about null checking when comparing the Create command with the final Slices + create = pickRandom(CollectionAdminRequest.createCollection(coll, "conf1", 5, 2,0,0), CollectionAdminRequest.createCollection(coll, "conf1", 5, 1,1,0), CollectionAdminRequest.createCollection(coll, "conf1", 5, 0,1,1), CollectionAdminRequest.createCollection(coll, "conf1", 5, 1,0,1), diff --git a/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java b/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java index abd394a9df6..d0d4f78b67e 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java @@ -101,9 +101,7 @@ public class ReplicationFactorTest extends AbstractFullDistribZkTestBase { CollectionAdminResponse resp = createCollection(testCollectionName, numShards, replicationFactor, maxShardsPerNode); if (resp.getResponse().get("failure") != null) { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); - req.process(cloudClient); + CollectionAdminRequest.deleteCollection(testCollectionName).process(cloudClient); resp = createCollection(testCollectionName, numShards, replicationFactor, maxShardsPerNode); diff --git a/solr/core/src/test/org/apache/solr/cloud/RollingRestartTest.java b/solr/core/src/test/org/apache/solr/cloud/RollingRestartTest.java index 6a906bbc019..14586664ec0 100644 --- a/solr/core/src/test/org/apache/solr/cloud/RollingRestartTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/RollingRestartTest.java @@ -70,7 +70,7 @@ public class RollingRestartTest extends AbstractFullDistribZkTestBase { int n = random().nextInt(getShardCount()); String nodeName = cloudJettys.get(n).nodeName; log.info("Chose {} as overseer designate", nodeName); - new CollectionAdminRequest.AddRole().setRole("overseer").setNode(nodeName).process(cloudClient); + CollectionAdminRequest.addRole(nodeName,"overseer").process(cloudClient); designates.add(nodeName); designateJettys.add(cloudJettys.get(n)); } diff --git a/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java b/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java index 72f06943cf7..35ac5c02429 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java @@ -523,16 +523,12 @@ public class ShardSplitTest extends BasicDistributedZkTest { log.info("Starting testSplitShardWithRule"); String collectionName = "shardSplitWithRule"; - CollectionAdminRequest.Create createRequest = new CollectionAdminRequest.Create() - .setCollectionName(collectionName) - .setNumShards(1) - .setReplicationFactor(2) + CollectionAdminRequest.Create createRequest = CollectionAdminRequest.createCollection(collectionName,1,2) .setRule("shard:*,replica:<2,node:*"); CollectionAdminResponse response = createRequest.process(cloudClient); assertEquals(0, response.getStatus()); - CollectionAdminRequest.SplitShard splitShardRequest = new CollectionAdminRequest.SplitShard() - .setCollectionName(collectionName) + CollectionAdminRequest.SplitShard splitShardRequest = CollectionAdminRequest.splitShard(collectionName) .setShardName("shard1"); response = splitShardRequest.process(cloudClient); assertEquals(String.valueOf(response.getErrorMessages()), 0, response.getStatus()); diff --git a/solr/core/src/test/org/apache/solr/cloud/SharedFSAutoReplicaFailoverTest.java b/solr/core/src/test/org/apache/solr/cloud/SharedFSAutoReplicaFailoverTest.java index 9c345fdf979..9c839f6f9f0 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SharedFSAutoReplicaFailoverTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SharedFSAutoReplicaFailoverTest.java @@ -146,12 +146,8 @@ public class SharedFSAutoReplicaFailoverTest extends AbstractFullDistribZkTestBa // serially private void testBasics() throws Exception { String collection1 = "solrj_collection"; - Create createCollectionRequest = new Create() - .setCollectionName(collection1) - .setNumShards(2) - .setReplicationFactor(2) + Create createCollectionRequest = CollectionAdminRequest.createCollection(collection1,"conf1",2,2) .setMaxShardsPerNode(2) - .setConfigName("conf1") .setRouterField("myOwnField") .setAutoAddReplicas(true); CollectionAdminResponse response = createCollectionRequest.process(cloudClient); @@ -161,12 +157,8 @@ public class SharedFSAutoReplicaFailoverTest extends AbstractFullDistribZkTestBa waitForRecoveriesToFinish(collection1, false); String collection2 = "solrj_collection2"; - createCollectionRequest = new Create() - .setCollectionName(collection2) - .setNumShards(2) - .setReplicationFactor(2) + createCollectionRequest = CollectionAdminRequest.createCollection(collection2,"conf1",2,2) .setMaxShardsPerNode(2) - .setConfigName("conf1") .setRouterField("myOwnField") .setAutoAddReplicas(false); CollectionAdminResponse response2 = createCollectionRequest.process(getCommonCloudSolrClient()); @@ -177,12 +169,8 @@ public class SharedFSAutoReplicaFailoverTest extends AbstractFullDistribZkTestBa waitForRecoveriesToFinish(collection2, false); String collection3 = "solrj_collection3"; - createCollectionRequest = new Create() - .setCollectionName(collection3) - .setNumShards(5) - .setReplicationFactor(1) + createCollectionRequest = CollectionAdminRequest.createCollection(collection3,"conf1",5,1) .setMaxShardsPerNode(1) - .setConfigName("conf1") .setRouterField("myOwnField") .setAutoAddReplicas(true); CollectionAdminResponse response3 = createCollectionRequest.process(getCommonCloudSolrClient()); @@ -194,12 +182,8 @@ public class SharedFSAutoReplicaFailoverTest extends AbstractFullDistribZkTestBa // a collection has only 1 replica per a shard String collection4 = "solrj_collection4"; - createCollectionRequest = new Create() - .setCollectionName(collection4) - .setNumShards(5) - .setReplicationFactor(1) + createCollectionRequest = CollectionAdminRequest.createCollection(collection4,"conf1",5,1) .setMaxShardsPerNode(5) - .setConfigName("conf1") .setRouterField("text") .setAutoAddReplicas(true); CollectionAdminResponse response4 = createCollectionRequest.process(getCommonCloudSolrClient()); diff --git a/solr/core/src/test/org/apache/solr/cloud/SimpleCollectionCreateDeleteTest.java b/solr/core/src/test/org/apache/solr/cloud/SimpleCollectionCreateDeleteTest.java index abc08190957..3e18ce01373 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SimpleCollectionCreateDeleteTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SimpleCollectionCreateDeleteTest.java @@ -39,10 +39,7 @@ public class SimpleCollectionCreateDeleteTest extends AbstractFullDistribZkTestB } } String collectionName = "SimpleCollectionCreateDeleteTest"; - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create() - .setCollectionName(collectionName) - .setNumShards(1) - .setReplicationFactor(1) + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,1,1) .setCreateNodeSet(overseerNode) .setStateFormat(2); @@ -51,17 +48,13 @@ public class SimpleCollectionCreateDeleteTest extends AbstractFullDistribZkTestB if (request.get("success") != null) { assertTrue(cloudClient.getZkStateReader().getZkClient().exists(ZkStateReader.COLLECTIONS_ZKNODE + "/" + collectionName, false)); - CollectionAdminRequest.Delete delete = new CollectionAdminRequest.Delete(); - delete.setCollectionName(collectionName); + CollectionAdminRequest delete = CollectionAdminRequest.deleteCollection(collectionName); cloudClient.request(delete); assertFalse(cloudClient.getZkStateReader().getZkClient().exists(ZkStateReader.COLLECTIONS_ZKNODE + "/" + collectionName, false)); // create collection again on a node other than the overseer leader - create = new CollectionAdminRequest.Create() - .setCollectionName(collectionName) - .setNumShards(1) - .setReplicationFactor(1) + create = CollectionAdminRequest.createCollection(collectionName,1,1) .setCreateNodeSet(notOverseerNode) .setStateFormat(2); request = create.process(cloudClient).getResponse(); diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java b/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java index 74ad7bd62b2..43b018eb1d9 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java @@ -185,13 +185,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase { String cname = "clusterStatusZNodeVersion"; try (CloudSolrClient client = createCloudClient(null)) { - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create() - .setCollectionName(cname) - .setMaxShardsPerNode(1) - .setNumShards(1) - .setReplicationFactor(1) - .setConfigName("conf1"); - create.process(client); + CollectionAdminRequest.createCollection(cname,"conf1",1,1).setMaxShardsPerNode(1).process(client); waitForRecoveriesToFinish(cname, true); @@ -213,9 +207,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase { Integer znodeVersion = (Integer) collection.get("znodeVersion"); assertNotNull(znodeVersion); - CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica() - .setCollectionName(cname) - .setShardName("shard1"); + CollectionAdminRequest.AddReplica addReplica = CollectionAdminRequest.addReplicaToShard(cname, "shard1"); addReplica.process(client); waitForRecoveriesToFinish(cname, true); @@ -628,13 +620,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase { try (CloudSolrClient client = createCloudClient(null)) { client.connect(); - new CollectionAdminRequest.Create() - .setCollectionName("testClusterStateMigration") - .setNumShards(1) - .setReplicationFactor(1) - .setConfigName("conf1") - .setStateFormat(1) - .process(client); + CollectionAdminRequest.createCollection("testClusterStateMigration","conf1",1,1).setStateFormat(1).process(client); waitForRecoveriesToFinish("testClusterStateMigration", true); @@ -647,9 +633,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase { } client.commit("testClusterStateMigration"); - new CollectionAdminRequest.MigrateClusterState() - .setCollectionName("testClusterStateMigration") - .process(client); + CollectionAdminRequest.migrateCollectionFormat("testClusterStateMigration").process(client); client.getZkStateReader().forceUpdateCollection("testClusterStateMigration"); diff --git a/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java b/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java index d7b9d8aeaec..b4862567a9f 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java @@ -73,17 +73,11 @@ public class TestRandomRequestDistribution extends AbstractFullDistribZkTestBase */ private void testRequestTracking() throws Exception { - new CollectionAdminRequest.Create() - .setCollectionName("a1x2") - .setNumShards(1) - .setReplicationFactor(2) + CollectionAdminRequest.createCollection("a1x2",1,2) .setCreateNodeSet(nodeNames.get(0) + ',' + nodeNames.get(1)) .process(cloudClient); - new CollectionAdminRequest.Create() - .setCollectionName("b1x1") - .setNumShards(1) - .setReplicationFactor(1) + CollectionAdminRequest.createCollection("b1x1",1,1) .setCreateNodeSet(nodeNames.get(2)) .process(cloudClient); @@ -134,10 +128,7 @@ public class TestRandomRequestDistribution extends AbstractFullDistribZkTestBase private void testQueryAgainstDownReplica() throws Exception { log.info("Creating collection 'football' with 1 shard and 2 replicas"); - new CollectionAdminRequest.Create() - .setCollectionName("football") - .setNumShards(1) - .setReplicationFactor(2) + CollectionAdminRequest.createCollection("football",1,2) .setCreateNodeSet(nodeNames.get(0) + ',' + nodeNames.get(1)) .process(cloudClient); diff --git a/solr/core/src/test/org/apache/solr/cloud/TestRequestForwarding.java b/solr/core/src/test/org/apache/solr/cloud/TestRequestForwarding.java index 8d85bf682a1..febbe335300 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestRequestForwarding.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestRequestForwarding.java @@ -72,11 +72,7 @@ public class TestRequestForwarding extends SolrTestCaseJ4 { private void createCollection(String name, String config) throws Exception { CollectionAdminResponse response; - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create(); - create.setConfigName(config); - create.setCollectionName(name); - create.setNumShards(2); - create.setReplicationFactor(1); + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(name,config,2,1); create.setMaxShardsPerNode(1); response = create.process(solrCluster.getSolrClient()); diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java index d85601190a4..042c1114d46 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java @@ -174,10 +174,7 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase { String configName = "solrCloudCollectionConfig"; miniCluster.uploadConfigSet(SolrTestCaseJ4.TEST_PATH().resolve("collection1/conf"), configName); - CollectionAdminRequest.Create createRequest = new CollectionAdminRequest.Create(); - createRequest.setCollectionName(collectionName); - createRequest.setNumShards(NUM_SHARDS); - createRequest.setReplicationFactor(REPLICATION_FACTOR); + CollectionAdminRequest.Create createRequest = CollectionAdminRequest.createCollection(collectionName,NUM_SHARDS,REPLICATION_FACTOR); Properties properties = new Properties(); properties.put(CoreDescriptor.CORE_CONFIG, "solrconfig-tlog.xml"); properties.put("solr.tests.maxBufferedDocs", "100000"); @@ -216,9 +213,7 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase { assertEquals(1, rsp.getResults().getNumFound()); // delete the collection we created earlier - CollectionAdminRequest.Delete deleteRequest = new CollectionAdminRequest.Delete(); - deleteRequest.setCollectionName(collectionName); - deleteRequest.process(cloudSolrClient); + CollectionAdminRequest.deleteCollection(collectionName).process(cloudSolrClient); AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName, zkStateReader, true, true, 330); } diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java index d2f78736f6f..184cd9018db 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java @@ -173,7 +173,7 @@ public class TestSolrCloudWithSecureImpersonation extends SolrTestCaseJ4 { private void create1ShardCollection(String name, String config, MiniSolrCloudCluster solrCluster) throws Exception { CollectionAdminResponse response; - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create() { + CollectionAdminRequest.Create create = new CollectionAdminRequest.Create(name,config,1,1,0,0) { @Override public SolrParams getParams() { ModifiableSolrParams msp = new ModifiableSolrParams(super.getParams()); @@ -181,10 +181,6 @@ public class TestSolrCloudWithSecureImpersonation extends SolrTestCaseJ4 { return msp; } }; - create.setConfigName(config); - create.setCollectionName(name); - create.setNumShards(1); - create.setReplicationFactor(1); create.setMaxShardsPerNode(1); response = create.process(solrCluster.getSolrClient()); diff --git a/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java b/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java index c395d205b64..737e16e33ce 100644 --- a/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java +++ b/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java @@ -62,10 +62,7 @@ public class TestBlobHandler extends AbstractFullDistribZkTestBase { try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) { CollectionAdminResponse response1; - CollectionAdminRequest.Create createCollectionRequest = new CollectionAdminRequest.Create() - .setCollectionName(".system") - .setNumShards(1) - .setReplicationFactor(2); + CollectionAdminRequest.Create createCollectionRequest = CollectionAdminRequest.createCollection(".system",1,2); response1 = createCollectionRequest.process(client); assertEquals(0, response1.getStatus()); assertTrue(response1.isSuccess()); @@ -119,10 +116,7 @@ public class TestBlobHandler extends AbstractFullDistribZkTestBase { public static void createSystemCollection(SolrClient client) throws SolrServerException, IOException { CollectionAdminResponse response1; - CollectionAdminRequest.Create createCollectionRequest = new CollectionAdminRequest.Create() - .setCollectionName(".system") - .setNumShards(1) - .setReplicationFactor(2); + CollectionAdminRequest.Create createCollectionRequest = CollectionAdminRequest.createCollection(".system",1,2); response1 = createCollectionRequest.process(client); assertEquals(0, response1.getStatus()); assertTrue(response1.isSuccess()); diff --git a/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java b/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java index f3bcc16200e..c35593221ef 100644 --- a/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java +++ b/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java @@ -196,20 +196,11 @@ public class TestDistribIDF extends SolrTestCaseJ4 { private void createCollection(String name, String config, String router) throws Exception { CollectionAdminResponse response; if (router.equals(ImplicitDocRouter.NAME)) { - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create(); - create.setConfigName(config); - create.setCollectionName(name); - create.setReplicationFactor(1); + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollectionWithImplicitRouter(name,config,"a,b,c",1); create.setMaxShardsPerNode(1); - create.setRouterName(router); - create.setShards("a,b,c"); response = create.process(solrCluster.getSolrClient()); } else { - CollectionAdminRequest.Create create = new CollectionAdminRequest.Create(); - create.setConfigName(config); - create.setCollectionName(name); - create.setNumShards(2); - create.setReplicationFactor(1); + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(name,config,2,1); create.setMaxShardsPerNode(1); response = create.process(solrCluster.getSolrClient()); } 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 6c00b5cdc72..b3d8a3faeea 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 @@ -33,7 +33,6 @@ 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; import org.apache.solr.common.cloud.ImplicitDocRouter; import org.apache.solr.common.cloud.Replica; @@ -68,14 +67,11 @@ public abstract class CollectionAdminRequest public CollectionAdminRequest(String path, CollectionAction action) { super(METHOD.GET, path); - this.action = action; + this.action = checkNotNull("action", action); } @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; @@ -116,12 +112,6 @@ public abstract class CollectionAdminRequest return asyncId; } - /** - * @deprecated Use {@link #processAsync(String, SolrClient)} or {@link #processAsync(SolrClient)} - */ - @Deprecated - public AsyncCollectionAdminRequest setAsyncId(String id){return this;}; - /** * Process this request asynchronously, generating and returning a request id * @param client a Solr client @@ -189,12 +179,9 @@ public abstract class CollectionAdminRequest public AsyncCollectionSpecificAdminRequest(CollectionAction action, String collection) { super(action); - this.collection = collection; + this.collection = checkNotNull("collection", collection); } - @Deprecated - public abstract AsyncCollectionSpecificAdminRequest setCollectionName(String collection); - public String getCollectionName() { return collection; } @@ -202,8 +189,6 @@ public abstract class CollectionAdminRequest @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (collection == null) - throw new IllegalArgumentException("You must call setCollectionName() on this request"); params.set(CoreAdminParams.NAME, collection); return params; } @@ -216,23 +201,13 @@ public abstract class CollectionAdminRequest public AsyncShardSpecificAdminRequest(CollectionAction action, String collection, String shard) { super(action); - this.collection = collection; - this.shard = shard; + this.collection = checkNotNull("collection",collection); + this.shard = checkNotNull("shard",shard); } - @Deprecated - public abstract AsyncShardSpecificAdminRequest setCollectionName(String collection); - - @Deprecated - public abstract AsyncShardSpecificAdminRequest setShardName(String shard); - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (collection == null) - throw new IllegalArgumentException("You must call setCollectionName() on this request"); - if (shard == null) - throw new IllegalArgumentException("You must call setShardName() on this request"); params.set(CoreAdminParams.COLLECTION, collection); params.set(CoreAdminParams.SHARD, shard); return params; @@ -246,21 +221,14 @@ public abstract class CollectionAdminRequest public ShardSpecificAdminRequest(CollectionAction action, String collection, String shard) { super(action); + this.collection = checkNotNull("collection",collection); + this.shard = checkNotNull("shard",shard); } - @Deprecated - public abstract ShardSpecificAdminRequest setCollectionName(String collection); - - @Deprecated - public abstract ShardSpecificAdminRequest setShardName(String shard); @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (collection == null) - throw new IllegalArgumentException("You must call setCollectionName() on this request"); - if (shard == null) - throw new IllegalArgumentException("You must call setShardName() on this request"); params.set(CoreAdminParams.COLLECTION, collection); params.set(CoreAdminParams.SHARD, shard); return params; @@ -284,26 +252,14 @@ public abstract class CollectionAdminRequest public CollectionAdminRoleRequest(CollectionAction action, String node, String role) { super(action); - this.node = node; - this.role = role; + this.role = checkNotNull("role",role); + this.node = checkNotNull("node",node); } - @Override - public CollectionAdminRoleRequest setAsyncId(String id) { - this.asyncId = id; - return this; - } - - @Deprecated - public abstract CollectionAdminRoleRequest setNode(String node); - public String getNode() { return this.node; } - @Deprecated - public abstract CollectionAdminRoleRequest setRole(String role); - public String getRole() { return this.role; } @@ -341,7 +297,7 @@ public abstract class CollectionAdminRequest * @param numReplicas the replication factor of the collection (same as numNrtReplicas) */ public static Create createCollection(String collection, String config, int numShards, int numReplicas) { - return new Create(collection, config, numShards, numReplicas, 0, 0); + return new Create(collection, config, numShards, numReplicas, null, null); } /** @@ -379,10 +335,7 @@ public abstract class CollectionAdminRequest * @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 numNrtReplicas, int numTlogReplicas, int numPullReplicas) { - Create createRequest = new Create(collection, config, shards, numNrtReplicas); - createRequest.tlogReplicas = numTlogReplicas; - createRequest.pullReplicas = numPullReplicas; - return createRequest; + return new Create(collection, config, ImplicitDocRouter.NAME, null, checkNotNull("shards",shards), numNrtReplicas, numTlogReplicas, numPullReplicas); } // CREATE request @@ -404,38 +357,34 @@ public abstract class CollectionAdminRequest protected Integer stateFormat; private String[] rule , snitch; - /** - * @deprecated Use {@link #createCollection(String, String, int, int, int, int)} - */ - @Deprecated - public Create() { - super(CollectionAction.CREATE, null); + /** Constructor intended for typical use cases */ + protected Create(String collection, String config, Integer numShards, Integer numNrtReplicas, Integer numTlogReplicas, Integer numPullReplicas) { // TODO: maybe add other constructors + this(collection, config, null, numShards, null, numNrtReplicas, numTlogReplicas, numPullReplicas); + } + + /** Constructor that assumes {@link ImplicitDocRouter#NAME} and an explicit list of shards */ + protected Create(String collection, String config, String shards, int numNrtReplicas) { + this(collection, config, ImplicitDocRouter.NAME, null, checkNotNull("shards",shards), numNrtReplicas, null, null); } - private Create(String collection, String config, int numShards, int numNrtReplicas, int numTlogReplicas, int numPullReplicas) { // TODO: maybe add other constructors + private Create(String collection, String config, String routerName, Integer numShards, String shards, Integer numNrtReplicas, Integer numTlogReplicas, Integer numPullReplicas) { super(CollectionAction.CREATE, SolrIdentifierValidator.validateCollectionName(collection)); + // NOTE: there's very little we can assert about the args because nothing but "collection" is required by the server + if ((null != shards) && (null != numShards)) { + throw new IllegalArgumentException("Can not specify both a numShards and a list of shards"); + } this.configName = config; + this.routerName = routerName; this.numShards = numShards; + this.setShards(shards); this.nrtReplicas = numNrtReplicas; - this.pullReplicas = numPullReplicas; this.tlogReplicas = numTlogReplicas; + this.pullReplicas = numPullReplicas; } - private Create(String collection, String config, String shards, int numNrtReplicas) { - super(CollectionAction.CREATE, SolrIdentifierValidator.validateCollectionName(collection)); - this.configName = config; - this.nrtReplicas = numNrtReplicas; - this.shards = shards; - this.routerName = ImplicitDocRouter.NAME; - } - - @Deprecated - public Create setConfigName(String config) { this.configName = config; return this; } public Create setCreateNodeSet(String nodeSet) { this.createNodeSet = nodeSet; return this; } public Create setRouterName(String routerName) { this.routerName = routerName; return this; } public Create setRouterField(String routerField) { this.routerField = routerField; return this; } - @Deprecated - 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 setNrtReplicas(Integer nrtReplicas) { this.nrtReplicas = nrtReplicas; return this;} @@ -470,33 +419,15 @@ public abstract class CollectionAdminRequest * @throws IllegalArgumentException if any of the shard names contain invalid characters. */ public Create setShards(String shards) { - for (String shard : shards.split(",")) { - SolrIdentifierValidator.validateShardName(shard); + if (null != shards) { + for (String shard : shards.split(",")) { + SolrIdentifierValidator.validateShardName(shard); + } } this.shards = shards; return this; } - /** - * Provide the name of the collection to be created. - * - * Collection names must consist entirely of periods, underscores and alphanumerics. Other characters are not allowed. - * - * @throws IllegalArgumentException if the collection name contains invalid characters. - */ - @Deprecated - public Create setCollectionName(String collectionName) throws SolrException { - this.collection = SolrIdentifierValidator.validateCollectionName(collectionName); - return this; - } - - @Override - @Deprecated - public Create setAsyncId(String id) { - this.asyncId = id; - return this; - } - public Properties getProperties() { return properties; } @@ -576,31 +507,9 @@ public abstract class CollectionAdminRequest // RELOAD request public static class Reload extends AsyncCollectionSpecificAdminRequest { - /** - * @deprecated use {@link #reloadCollection(String)} - */ - @Deprecated - public Reload() { - super(CollectionAction.RELOAD, null); - } - private Reload(String collection) { super(CollectionAction.RELOAD, collection); } - - @Override - @Deprecated - public Reload setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public Reload setAsyncId(String id) { - this.asyncId = id; - return this; - } } public static class DeleteNode extends AsyncCollectionAdminRequest { @@ -611,7 +520,7 @@ public abstract class CollectionAdminRequest */ public DeleteNode(String node) { super(CollectionAction.DELETENODE); - this.node = node; + this.node = checkNotNull("node",node); } @Override public SolrParams getParams() { @@ -633,8 +542,8 @@ public abstract class CollectionAdminRequest */ public ReplaceNode(String source, String target) { super(CollectionAction.REPLACENODE); - this.source = source; - this.target = target; + this.source = checkNotNull("source",source); + this.target = checkNotNull("target",target); } public ReplaceNode setParallel(Boolean flag) { @@ -660,18 +569,18 @@ public abstract class CollectionAdminRequest public MoveReplica(String collection, String replica, String targetNode) { super(CollectionAction.MOVEREPLICA); - this.collection = collection; - this.replica = replica; - this.targetNode = targetNode; + this.collection = checkNotNull("collection",collection); + this.replica = checkNotNull("replica",replica); + this.targetNode = checkNotNull("targetNode",targetNode); this.randomlyMoveReplica = false; } public MoveReplica(String collection, String shard, String fromNode, String targetNode) { super(CollectionAction.MOVEREPLICA); - this.collection = collection; - this.shard = shard; - this.fromNode = fromNode; - this.targetNode = targetNode; + this.collection = checkNotNull("collection",collection); + this.shard = checkNotNull("shard",shard); + this.fromNode = checkNotNull("fromNode",fromNode); + this.targetNode = checkNotNull("targetNode",targetNode); this.randomlyMoveReplica = true; } @@ -724,13 +633,7 @@ public abstract class CollectionAdminRequest public RebalanceLeaders(String collection) { super(CollectionAction.REBALANCELEADERS); - this.collection = collection; - } - - @Override - public RebalanceLeaders setAsyncId(String id) { - this.asyncId = id; - return this; + this.collection = checkNotNull("collection",collection); } @Override @@ -762,31 +665,10 @@ public abstract class CollectionAdminRequest // DELETE request public static class Delete extends AsyncCollectionSpecificAdminRequest { - /** - * @deprecated Use {@link #deleteCollection(String)} - */ - @Deprecated - public Delete() { - super(CollectionAction.DELETE, null); - } - private Delete(String collection) { super(CollectionAction.DELETE, collection); } - @Override - @Deprecated - public Delete setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public Delete setAsyncId(String id) { - this.asyncId = id; - return this; - } } public static Backup backupCollection(String collection, String backupName) { @@ -807,20 +689,6 @@ public abstract class CollectionAdminRequest this.repositoryName = Optional.empty(); } - @Override - @Deprecated - public Backup setAsyncId(String id) { - this.asyncId = id; - return this; - } - - @Override - @Deprecated - public Backup setCollectionName(String collection) { - this.collection = collection; - return this; - } - public String getLocation() { return location; } @@ -901,18 +769,6 @@ public abstract class CollectionAdminRequest this.backupName = backupName; } - @Override - public Restore setAsyncId(String id) { - this.asyncId = id; - return this; - } - - @Override - public Restore setCollectionName(String collection) { - this.collection = collection; - return this; - } - public String getLocation() { return location; } @@ -1007,7 +863,7 @@ public abstract class CollectionAdminRequest // This is because the setCollectionName method is deprecated. static T checkNotNull(String param, T value) { if (value == null) { - throw new NullPointerException("Please specify a value for parameter " + param); + throw new NullPointerException("Please specify a non-null value for parameter " + param); } return value; } @@ -1029,12 +885,6 @@ public abstract class CollectionAdminRequest return commitName; } - @Override - public AsyncCollectionSpecificAdminRequest setCollectionName (String collection) { - this.collection = checkNotNull(CoreAdminParams.COLLECTION ,collection); - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); @@ -1061,12 +911,6 @@ public abstract class CollectionAdminRequest return commitName; } - @Override - public AsyncCollectionSpecificAdminRequest setCollectionName (String collection) { - this.collection = checkNotNull(CoreAdminParams.COLLECTION ,collection); - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); @@ -1086,12 +930,6 @@ public abstract class CollectionAdminRequest return collection; } - @Override - public AsyncCollectionSpecificAdminRequest setCollectionName (String collection) { - this.collection = checkNotNull(CoreAdminParams.COLLECTION ,collection); - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); @@ -1131,46 +969,10 @@ public abstract class CollectionAdminRequest return this; } - /** - * @deprecated use {@link #createShard(String, String)} - */ - @Deprecated - public CreateShard() { - super(CollectionAction.CREATESHARD, null, null); - } - private CreateShard(String collection, String shard) { super(CollectionAction.CREATESHARD, collection, SolrIdentifierValidator.validateShardName(shard)); } - @Override - @Deprecated - public CreateShard setCollectionName(String collection) { - this.collection = collection; - return this; - } - - /** - * Provide the name of the shard to be created. - * - * Shard names must consist entirely of periods, underscores, hyphens, and alphanumerics. Other characters are not allowed. - * - * @throws IllegalArgumentException if the shard name contains invalid characters. - */ - @Override - @Deprecated - public CreateShard setShardName(String shardName) { - this.shard = SolrIdentifierValidator.validateShardName(shardName); - return this; - } - - @Override - @Deprecated - public CreateShard setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); @@ -1204,15 +1006,7 @@ public abstract class CollectionAdminRequest private SplitShard(String collection) { super(CollectionAction.SPLITSHARD); - this.collection = collection; - } - - /** - * @deprecated Use {@link #splitShard(String)} - */ - @Deprecated - public SplitShard() { - super(CollectionAction.SPLITSHARD); + this.collection = checkNotNull("collection",collection); } public SplitShard setRanges(String ranges) { this.ranges = ranges; return this; } @@ -1236,32 +1030,15 @@ public abstract class CollectionAdminRequest return this; } - @Deprecated - public SplitShard setCollectionName(String collection) { - this.collection = collection; - return this; - } - public SplitShard setShardName(String shard) { this.shard = shard; return this; } - @Override - @Deprecated - public SplitShard setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - if(this.collection == null) { - throw new IllegalArgumentException("You must set collection name for this request."); - } - params.set(CollectionAdminParams.COLLECTION, collection); if (this.shard == null && this.splitKey == null) { @@ -1293,14 +1070,6 @@ public abstract class CollectionAdminRequest private Boolean deleteInstanceDir; private Boolean deleteDataDir; - /** - * @deprecated Use {@link #deleteShard(String, String)} - */ - @Deprecated - public DeleteShard() { - super(CollectionAction.DELETESHARD, null, null); - } - private DeleteShard(String collection, String shard) { super(CollectionAction.DELETESHARD, collection, shard); } @@ -1323,27 +1092,6 @@ public abstract class CollectionAdminRequest return this; } - @Override - @Deprecated - public DeleteShard setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public DeleteShard setShardName(String shard) { - this.shard = shard; - return this; - } - - @Override - @Deprecated - public DeleteShard setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -1370,33 +1118,9 @@ public abstract class CollectionAdminRequest // FORCELEADER request public static class ForceLeader extends ShardSpecificAdminRequest { - - /** - * @deprecated Use {@link #forceLeaderElection(String, String)} - */ - @Deprecated - public ForceLeader() { - super(CollectionAction.FORCELEADER, null, null); - } - private ForceLeader(String collection, String shard) { super(CollectionAction.FORCELEADER, collection, shard); } - - @Override - @Deprecated - public ForceLeader setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public ForceLeader setShardName(String shard) { - this.shard = shard; - return this; - } - } /** @@ -1431,21 +1155,7 @@ public abstract class CollectionAdminRequest private RequestStatus(String requestId) { super(CollectionAction.REQUESTSTATUS); - this.requestId = requestId; - } - - /** - * @deprecated Use {@link #requestStatus(String)} - */ - @Deprecated - public RequestStatus() { - super(CollectionAction.REQUESTSTATUS); - } - - @Deprecated - public RequestStatus setRequestId(String requestId) { - this.requestId = requestId; - return this; + this.requestId = checkNotNull("requestId",requestId); } public String getRequestId() { @@ -1455,8 +1165,6 @@ public abstract class CollectionAdminRequest @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - if (requestId == null) - throw new IllegalArgumentException("You must call setRequestId() on this request"); params.set(CoreAdminParams.REQUESTID, requestId); return params; } @@ -1492,11 +1200,14 @@ public abstract class CollectionAdminRequest * Returns a SolrRequest to delete an asynchronous request status */ public static DeleteStatus deleteAsyncId(String requestId) { - return new DeleteStatus(requestId); + return new DeleteStatus(checkNotNull("requestId",requestId), null); } + /** + * Returns a SolrRequest to delete a all asynchronous request statuses + */ public static DeleteStatus deleteAllAsyncIds() { - return new DeleteStatus().setFlush(true); + return new DeleteStatus(null, true); } // DELETESTATUS request @@ -1505,29 +1216,15 @@ public abstract class CollectionAdminRequest protected String requestId = null; protected Boolean flush = null; - private DeleteStatus(String requestId) { + private DeleteStatus(String requestId, Boolean flush) { super(CollectionAction.DELETESTATUS); + if (requestId == null && flush == null) + throw new IllegalArgumentException("Either requestid or flush parameter must be specified."); + if (requestId != null && flush != null) + throw new IllegalArgumentException("Both requestid and flush parameters can not be specified together."); + this.requestId = requestId; - } - - /** - * @deprecated Use {@link #deleteAsyncId(String)} or {@link #deleteAllAsyncIds()} - */ - @Deprecated - public DeleteStatus() { - super(CollectionAction.DELETESTATUS); - } - - @Deprecated - public DeleteStatus setRequestId(String requestId) { - this.requestId = requestId; - return this; - } - - @Deprecated - public DeleteStatus setFlush(Boolean flush) { this.flush = flush; - return this; } public String getRequestId() { @@ -1541,10 +1238,6 @@ public abstract class CollectionAdminRequest @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - if (requestId == null && flush == null) - throw new IllegalArgumentException("Either requestid or flush parameter must be specified."); - if (requestId != null && flush != null) - throw new IllegalArgumentException("Both requestid and flush parameters can not be specified together."); if (requestId != null) params.set(CoreAdminParams.REQUESTID, requestId); if (flush != null) @@ -1577,51 +1270,17 @@ public abstract class CollectionAdminRequest private CreateAlias(String aliasName, String aliasedCollections) { super(CollectionAction.CREATEALIAS); this.aliasName = SolrIdentifierValidator.validateAliasName(aliasName); - this.aliasedCollections = aliasedCollections; - } - - /** - * @deprecated Use {@link #createAlias(String, String)} - */ - @Deprecated - public CreateAlias() { - super(CollectionAction.CREATEALIAS); - } - - /** - * Provide the name of the alias to be created. - * - * Alias names must consist entirely of periods, underscores and alphanumerics. Other characters are not allowed. - * - * @throws IllegalArgumentException if the alias name contains invalid characters. - */ - @Deprecated - public CreateAlias setAliasName(String aliasName) { - this.aliasName = SolrIdentifierValidator.validateAliasName(aliasName); - return this; + this.aliasedCollections = checkNotNull("aliasedCollections",aliasedCollections); } public String getAliasName() { return aliasName; } - @Deprecated - public CreateAlias setAliasedCollections(String alias) { - this.aliasedCollections = alias; - return this; - } - public String getAliasedCollections() { return this.aliasedCollections; } - @Override - @Deprecated - public CreateAlias setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); @@ -1646,28 +1305,7 @@ public abstract class CollectionAdminRequest private DeleteAlias(String aliasName) { super(CollectionAction.DELETEALIAS); - this.aliasName = aliasName; - } - - /** - * @deprecated Use {@link #deleteAlias(String)} - */ - @Deprecated - public DeleteAlias() { - super(CollectionAction.DELETEALIAS); - } - - @Deprecated - public DeleteAlias setAliasName(String aliasName) { - this.aliasName = aliasName; - return this; - } - - @Override - @Deprecated - public DeleteAlias setAsyncId(String id) { - this.asyncId = id; - return this; + this.aliasName = checkNotNull("aliasName",aliasName); } @Override @@ -1676,29 +1314,30 @@ public abstract class CollectionAdminRequest params.set(CoreAdminParams.NAME, aliasName); return params; } - - } /** * Returns a SolrRequest to add a replica of type {@link org.apache.solr.common.cloud.Replica.Type#NRT} to a shard in a collection + * */ public static AddReplica addReplicaToShard(String collection, String shard) { return addReplicaToShard(collection, shard, Replica.Type.NRT); } /** - * Returns a SolrRequest to add a replica of the specified type to a shard in a collection + * Returns a SolrRequest to add a replica of the specified type to a shard in a collection. + * If the replica type is null, the server default will be used. + * */ public static AddReplica addReplicaToShard(String collection, String shard, Replica.Type replicaType) { - return new AddReplica(collection, shard, null, replicaType); + return new AddReplica(collection, checkNotNull("shard",shard), null, replicaType); } /** * 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.NRT); + return new AddReplica(collection, null, checkNotNull("routeKey",routeKey), null); } // ADDREPLICA request @@ -1713,17 +1352,9 @@ public abstract class CollectionAdminRequest protected Properties properties; protected Replica.Type type; - /** - * @deprecated Use {@link #addReplicaByRouteKey(String, String)} or {@link #addReplicaToShard(String, String)} - */ - @Deprecated - public AddReplica() { - super(CollectionAction.ADDREPLICA); - } - private AddReplica(String collection, String shard, String routeKey, Replica.Type type) { super(CollectionAction.ADDREPLICA); - this.collection = collection; + this.collection = checkNotNull("collection",collection); this.shard = shard; this.routeKey = routeKey; this.type = type; @@ -1758,12 +1389,6 @@ public abstract class CollectionAdminRequest return routeKey; } - @Deprecated - public AddReplica setRouteKey(String routeKey) { - this.routeKey = routeKey; - return this; - } - public String getInstanceDir() { return instanceDir; } @@ -1782,25 +1407,6 @@ public abstract class CollectionAdminRequest return this; } - @Deprecated - public AddReplica setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Deprecated - public AddReplica setShardName(String shard) { - this.shard = shard; - return this; - } - - @Override - @Deprecated - public AddReplica setAsyncId(String id) { - this.asyncId = id; - return this; - } - public AddReplica setType(Replica.Type type) { this.type = type; return this; @@ -1809,18 +1415,14 @@ public abstract class CollectionAdminRequest @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); - if (collection == null) - throw new IllegalArgumentException("You must call setCollection() on this request"); params.add(CoreAdminParams.COLLECTION, collection); - if (shard == null || shard.isEmpty()) { - if (routeKey == null) { - throw new IllegalArgumentException("Either shard or routeKey must be provided"); - } - params.add(ShardParams._ROUTE_, routeKey); - } - else { + assert ((null == routeKey) ^ (null == shard)); + if (null != shard) { params.add(CoreAdminParams.SHARD, shard); } + if (null != routeKey) { + params.add(ShardParams._ROUTE_, routeKey); + } if (node != null) { params.add("node", node); } @@ -1845,14 +1447,14 @@ public abstract class CollectionAdminRequest * Returns a SolrRequest to delete a replica from a shard in a collection */ public static DeleteReplica deleteReplica(String collection, String shard, String replica) { - return new DeleteReplica(collection, shard, replica); + return new DeleteReplica(collection, checkNotNull("shard",shard), checkNotNull("replica",replica)); } /** * Returns a SolrRequest to remove a number of replicas from a specific shard */ public static DeleteReplica deleteReplicasFromShard(String collection, String shard, int count) { - return new DeleteReplica(collection, shard, count); + return new DeleteReplica(collection, checkNotNull("shard",shard), count); } public static DeleteReplica deleteReplicasFromAllShards(String collection, int count) { @@ -1870,14 +1472,6 @@ public abstract class CollectionAdminRequest private Boolean deleteIndexDir; private Integer count; - /** - * @deprecated Use {@link #deleteReplica(String, String, String)} - */ - @Deprecated - public DeleteReplica() { - super(CollectionAction.DELETEREPLICA, null); - } - private DeleteReplica(String collection, String shard, String replica) { super(CollectionAction.DELETEREPLICA, collection); this.shard = shard; @@ -1895,12 +1489,6 @@ public abstract class CollectionAdminRequest this.count = count; } - @Deprecated - public DeleteReplica setReplica(String replica) { - this.replica = replica; - return this; - } - public String getReplica() { return this.replica; } @@ -1914,25 +1502,6 @@ public abstract class CollectionAdminRequest return this.onlyIfDown; } - @Override - @Deprecated - public DeleteReplica setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Deprecated - public DeleteReplica setShardName(String shard) { - this.shard = shard; - return this; - } - - @Deprecated - public DeleteReplica setCount(Integer count) { - this.count = count; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -1940,8 +1509,6 @@ public abstract class CollectionAdminRequest // AsyncCollectionSpecificAdminRequest uses 'name' rather than 'collection' // TODO - deal with this inconsistency params.remove(CoreAdminParams.NAME); - if (this.collection == null) - throw new IllegalArgumentException("You must set a collection name for this request"); params.set(ZkStateReader.COLLECTION_PROP, this.collection); if (this.replica != null) @@ -1996,7 +1563,7 @@ public abstract class CollectionAdminRequest } /** - * Returns a SolrRequest to set a cluster property + * Returns a SolrRequest to set (or unset) a cluster property */ public static ClusterProp setClusterProperty(String propertyName, String propertyValue) { return new ClusterProp(propertyName, propertyValue); @@ -2008,36 +1575,16 @@ public abstract class CollectionAdminRequest private String propertyName; private String propertyValue; - /** - * @deprecated Use {@link #setClusterProperty(String, String)} - */ - @Deprecated - public ClusterProp() { - super(CollectionAction.CLUSTERPROP); - } - private ClusterProp(String propertyName, String propertyValue) { super(CollectionAction.CLUSTERPROP); - this.propertyName = propertyName; + this.propertyName = checkNotNull("propertyName",propertyName); this.propertyValue = propertyValue; } - @Deprecated - public ClusterProp setPropertyName(String propertyName) { - this.propertyName = propertyName; - return this; - } - public String getPropertyName() { return this.propertyName; } - @Deprecated - public ClusterProp setPropertyValue(String propertyValue) { - this.propertyValue = propertyValue; - return this; - } - public String getPropertyValue() { return this.propertyValue; } @@ -2075,47 +1622,21 @@ public abstract class CollectionAdminRequest private Integer forwardTimeout; private Properties properties; - /** - * @deprecated Use {@link #migrateData(String, String, String)} - */ - @Deprecated - public Migrate() { - super(CollectionAction.MIGRATE); - } - private Migrate(String collection, String targetCollection, String splitKey) { super(CollectionAction.MIGRATE); - this.collection = collection; - this.targetCollection = targetCollection; - this.splitKey = splitKey; - } - - @Deprecated - public Migrate setCollectionName(String collection) { - this.collection = collection; - return this; + this.collection = checkNotNull("collection",collection); + this.targetCollection = checkNotNull("targetCollection",targetCollection); + this.splitKey = checkNotNull("splitKey",splitKey); } public String getCollectionName() { return collection; } - @Deprecated - public Migrate setTargetCollection(String targetCollection) { - this.targetCollection = targetCollection; - return this; - } - public String getTargetCollection() { return this.targetCollection; } - @Deprecated - public Migrate setSplitKey(String splitKey) { - this.splitKey = splitKey; - return this; - } - public String getSplitKey() { return this.splitKey; } @@ -2138,13 +1659,6 @@ public abstract class CollectionAdminRequest return this.properties; } - @Override - @Deprecated - public Migrate setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -2173,32 +1687,9 @@ public abstract class CollectionAdminRequest // ADDROLE request public static class AddRole extends CollectionAdminRoleRequest { - - /** - * @deprecated Use {@link #addRole(String, String)} - */ - @Deprecated - public AddRole() { - super(CollectionAction.ADDROLE, null, null); - } - private AddRole(String node, String role) { super(CollectionAction.ADDROLE, node, role); } - - @Override - @Deprecated - public AddRole setNode(String node) { - this.node = node; - return this; - } - - @Override - @Deprecated - public AddRole setRole(String role) { - this.role = role; - return this; - } } /** @@ -2210,32 +1701,9 @@ public abstract class CollectionAdminRequest // REMOVEROLE request public static class RemoveRole extends CollectionAdminRoleRequest { - - /** - * @deprecated Use {@link #removeRole(String, String)} - */ - @Deprecated - public RemoveRole() { - super(CollectionAction.REMOVEROLE, null, null); - } - private RemoveRole(String node, String role) { super(CollectionAction.REMOVEROLE, node, role); } - - @Override - @Deprecated - public RemoveRole setNode(String node) { - this.node = node; - return this; - } - - @Override - @Deprecated - public RemoveRole setRole(String role) { - this.role = role; - return this; - } } /** @@ -2252,12 +1720,6 @@ public abstract class CollectionAdminRequest super(CollectionAction.OVERSEERSTATUS); } - @Override - @Deprecated - public OverseerStatus setAsyncId(String id) { - this.asyncId = id; - return this; - } } /** @@ -2377,51 +1839,25 @@ public abstract class CollectionAdminRequest private String propertyValue; private Boolean shardUnique; - /** - * @deprecated Use {@link #addReplicaProperty(String, String, String, String, String)} - */ - @Deprecated - public AddReplicaProp() { - super(CollectionAction.ADDREPLICAPROP, null, null); - } - private AddReplicaProp(String collection, String shard, String replica, String propertyName, String propertyValue) { super(CollectionAction.ADDREPLICAPROP, collection, shard); - this.replica = replica; - this.propertyName = propertyName; - this.propertyValue = propertyValue; + this.replica = checkNotNull("replica",replica); + this.propertyName = checkNotNull("propertyName",propertyName); + this.propertyValue = checkNotNull("propertyValue",propertyValue); } public String getReplica() { return replica; } - @Deprecated - public AddReplicaProp setReplica(String replica) { - this.replica = replica; - return this; - } - public String getPropertyName() { return propertyName; } - @Deprecated - public AddReplicaProp setPropertyName(String propertyName) { - this.propertyName = propertyName; - return this; - } - public String getPropertyValue() { return propertyValue; } - @Deprecated - public AddReplicaProp setPropertyValue(String propertyValue) { - this.propertyValue = propertyValue; - return this; - } - public Boolean getShardUnique() { return shardUnique; } @@ -2431,27 +1867,6 @@ public abstract class CollectionAdminRequest return this; } - @Override - @Deprecated - public AddReplicaProp setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public AddReplicaProp setShardName(String shard) { - this.shard = shard; - return this; - } - - @Override - @Deprecated - public AddReplicaProp setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -2482,61 +1897,20 @@ public abstract class CollectionAdminRequest private String replica; private String propertyName; - /** - * @deprecated Use {@link #deleteReplicaProperty(String, String, String, String)} - */ - @Deprecated - public DeleteReplicaProp() { - super(CollectionAction.DELETEREPLICAPROP, null, null); - } - private DeleteReplicaProp(String collection, String shard, String replica, String propertyName) { super(CollectionAction.DELETEREPLICAPROP, collection, shard); - this.replica = replica; - this.propertyName = propertyName; + this.replica = checkNotNull("replica",replica); + this.propertyName = checkNotNull("propertyName",propertyName); } public String getReplica() { return replica; } - @Deprecated - public DeleteReplicaProp setReplica(String replica) { - this.replica = replica; - return this; - } - public String getPropertyName() { return propertyName; } - @Deprecated - public DeleteReplicaProp setPropertyName(String propertyName) { - this.propertyName = propertyName; - return this; - } - - @Override - @Deprecated - public DeleteReplicaProp setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public DeleteReplicaProp setShardName(String shard) { - this.shard = shard; - return this; - } - - @Override - @Deprecated - public DeleteReplicaProp setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); @@ -2564,35 +1938,12 @@ public abstract class CollectionAdminRequest private MigrateClusterState(String collection) { super(CollectionAction.MIGRATESTATEFORMAT); - this.collection = collection; - } - - /** - * @deprecated Use {@link #migrateCollectionFormat(String)} - */ - @Deprecated - public MigrateClusterState() { - super(CollectionAction.MIGRATESTATEFORMAT); - } - - @Deprecated - public MigrateClusterState setCollectionName(String collection) { - this.collection = collection; - return this; - } - - @Override - @Deprecated - public MigrateClusterState setAsyncId(String id) { - this.asyncId = id; - return this; + this.collection = checkNotNull("collection",collection); } @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; } @@ -2615,28 +1966,14 @@ public abstract class CollectionAdminRequest private BalanceShardUnique(String collection, String propertyName) { super(CollectionAction.BALANCESHARDUNIQUE); - this.collection = collection; - this.propertyName = propertyName; - } - - /** - * @deprecated Use {@link #balanceReplicaProperty(String, String)} - */ - @Deprecated - public BalanceShardUnique() { - super(CollectionAction.BALANCESHARDUNIQUE); + this.collection = checkNotNull("collection",collection); + this.propertyName = checkNotNull("propertyName",propertyName); } public String getPropertyName() { return propertyName; } - @Deprecated - public BalanceShardUnique setPropertyName(String propertyName) { - this.propertyName = propertyName; - return this; - } - public Boolean getOnlyActiveNodes() { return onlyActiveNodes; } @@ -2655,23 +1992,10 @@ public abstract class CollectionAdminRequest return this; } - @Deprecated - public BalanceShardUnique setCollection(String collection) { - this.collection = collection; - return this; - } - public String getCollection() { return collection; } - @Override - @Deprecated - public BalanceShardUnique setAsyncId(String id) { - this.asyncId = id; - return this; - } - @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); 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 0f9b1475bb0..870aa343dfa 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 @@ -17,6 +17,7 @@ package org.apache.solr.client.solrj; import static org.apache.solr.common.params.CoreAdminParams.*; +import static org.apache.solr.common.params.CollectionAdminParams.FLUSH; import java.util.Iterator; import java.util.Set; @@ -37,135 +38,131 @@ import com.google.common.collect.Sets; public class CollectionAdminRequestRequiredParamsTest extends LuceneTestCase { public void testBalanceShardUnique() { - final CollectionAdminRequest.BalanceShardUnique request = new CollectionAdminRequest.BalanceShardUnique() - .setCollection("foo") - .setPropertyName("prop"); + CollectionAdminRequest.BalanceShardUnique request = CollectionAdminRequest.balanceReplicaProperty("foo","prop"); assertContainsParams(request.getParams(), ACTION, COLLECTION, "property"); + + request.setShardUnique(true); + assertContainsParams(request.getParams(), ACTION, COLLECTION, "property","shardUnique"); + + request.setOnlyActiveNodes(false); + assertContainsParams(request.getParams(), ACTION, COLLECTION, "property","shardUnique","onlyactivenodes"); + + request.setShardUnique(null); + assertContainsParams(request.getParams(), ACTION, COLLECTION, "property","onlyactivenodes"); + } public void testClusterProp() { - final CollectionAdminRequest.ClusterProp request = new CollectionAdminRequest.ClusterProp() - .setPropertyName("foo") - .setPropertyValue("bar"); + CollectionAdminRequest.ClusterProp request = CollectionAdminRequest.setClusterProperty("foo","bar"); assertContainsParams(request.getParams(), ACTION, NAME, "val"); } public void testAddRole() { - final CollectionAdminRequest.AddRole request = new CollectionAdminRequest.AddRole() - .setNode("node") - .setRole("role"); + CollectionAdminRequest.AddRole request = CollectionAdminRequest.addRole("node","role"); assertContainsParams(request.getParams(), ACTION, "node", "role"); } public void testRemoveRole() { - final CollectionAdminRequest.RemoveRole request = new CollectionAdminRequest.RemoveRole() - .setNode("node") - .setRole("role"); + CollectionAdminRequest.RemoveRole request = CollectionAdminRequest.removeRole("node","role"); assertContainsParams(request.getParams(), ACTION, "node", "role"); } public void testAddReplica() { - // with shard parameter - CollectionAdminRequest.AddReplica request = new CollectionAdminRequest.AddReplica() - .setShardName("shard") - .setCollectionName("collection"); + // with shard parameter and "client side" implicit type param + CollectionAdminRequest.AddReplica request = CollectionAdminRequest.addReplicaToShard("collection", "shard"); + assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, ZkStateReader.REPLICA_TYPE); + + // with only shard parameter and "server side" implicit type, so no param + request = CollectionAdminRequest.addReplicaToShard("collection", "shard", null); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD); // with route parameter - request = new CollectionAdminRequest.AddReplica() - .setRouteKey("route") - .setCollectionName("collection"); + request = CollectionAdminRequest.addReplicaByRouteKey("collection","route"); assertContainsParams(request.getParams(), ACTION, COLLECTION, ShardParams._ROUTE_); - // with type parameter - request = new CollectionAdminRequest.AddReplica() - .setShardName("shard") - .setCollectionName("collection") - .setType(Replica.Type.NRT); + // with explicit type parameter + request = CollectionAdminRequest.addReplicaToShard("collection", "shard", Replica.Type.NRT); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, ZkStateReader.REPLICA_TYPE); } public void testAddReplicaProp() { - final CollectionAdminRequest.AddReplicaProp request = new CollectionAdminRequest.AddReplicaProp() - .setShardName("shard") - .setCollectionName("collection") - .setReplica("replica") - .setPropertyName("prop") - .setPropertyValue("value"); + final CollectionAdminRequest.AddReplicaProp request = CollectionAdminRequest.addReplicaProperty + ("collection", "shard", "replica", "prop", "value"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, REPLICA, "property", "property.value"); } public void testClusterStatus() { - final CollectionAdminRequest.ClusterStatus request = new CollectionAdminRequest.ClusterStatus(); + final CollectionAdminRequest.ClusterStatus request = CollectionAdminRequest.getClusterStatus(); assertContainsParams(request.getParams(), ACTION); + + request.setCollectionName("foo"); + assertContainsParams(request.getParams(), ACTION, COLLECTION); + + request.setShardName("foo"); + assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD); + + request.setRouteKey("foo"); + request.setShardName(null); + assertContainsParams(request.getParams(), ACTION, COLLECTION, ShardParams._ROUTE_); + } public void testCreateShard() { - final CollectionAdminRequest.CreateShard request = new CollectionAdminRequest.CreateShard() - .setCollectionName("collection") - .setShardName("shard"); + final CollectionAdminRequest.CreateShard request = CollectionAdminRequest.createShard("collection","shard"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD); } public void testDeleteReplica() { - final CollectionAdminRequest.DeleteReplica request = new CollectionAdminRequest.DeleteReplica() - .setCollectionName("collection") - .setShardName("shard") - .setReplica("replica"); + final CollectionAdminRequest.DeleteReplica request = CollectionAdminRequest.deleteReplica("collection","shard","replica"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, REPLICA); + } public void testDeleteReplicaProp() { - final CollectionAdminRequest.DeleteReplicaProp request = new CollectionAdminRequest.DeleteReplicaProp() - .setCollectionName("collection") - .setShardName("shard") - .setReplica("replica") - .setPropertyName("foo"); + final CollectionAdminRequest.DeleteReplicaProp request = CollectionAdminRequest.deleteReplicaProperty + ("collection", "shard", "replica", "foo"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD, REPLICA, "property"); } public void testDeleteShard() { - final CollectionAdminRequest.DeleteShard request = new CollectionAdminRequest.DeleteShard() - .setCollectionName("collection") - .setShardName("shard"); + final CollectionAdminRequest.DeleteShard request = CollectionAdminRequest.deleteShard("collection","shard"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD); } public void testSplitShard() { - final CollectionAdminRequest.SplitShard request = new CollectionAdminRequest.SplitShard() - .setCollectionName("collection") + final CollectionAdminRequest.SplitShard request = CollectionAdminRequest.splitShard("collection") .setShardName("shard"); assertContainsParams(request.getParams(), ACTION, COLLECTION, SHARD); } public void testCreateCollection() { - final CollectionAdminRequest.Create request = new CollectionAdminRequest.Create() - .setCollectionName("collection"); - assertContainsParams(request.getParams(), ACTION, NAME); + // shortest form + assertContainsParams(CollectionAdminRequest.createCollection("foo", null, 1, 1).getParams(), + ACTION, NAME, ZkStateReader.NUM_SHARDS_PROP, + "replicationFactor", ZkStateReader.NRT_REPLICAS); + // shortest form w/ "explicitly" choosing "implicit" router + assertContainsParams(CollectionAdminRequest.createCollectionWithImplicitRouter("foo", null, "bar", 1).getParams(), + ACTION, NAME, "shards", "router.name", + "replicationFactor", ZkStateReader.NRT_REPLICAS); } public void testReloadCollection() { - final CollectionAdminRequest.Reload request = new CollectionAdminRequest.Reload() - .setCollectionName("collection"); + final CollectionAdminRequest.Reload request = CollectionAdminRequest.reloadCollection("collection"); assertContainsParams(request.getParams(), ACTION, NAME); } public void testDeleteCollection() { - final CollectionAdminRequest.Delete request = new CollectionAdminRequest.Delete() - .setCollectionName("collection"); + final CollectionAdminRequest.Delete request = CollectionAdminRequest.deleteCollection("collection"); assertContainsParams(request.getParams(), ACTION, NAME); } public void testCreateAlias() { - final CollectionAdminRequest.CreateAlias request = new CollectionAdminRequest.CreateAlias() - .setAliasName("name") - .setAliasedCollections("collections"); + final CollectionAdminRequest.CreateAlias request = CollectionAdminRequest.createAlias("name","collections"); assertContainsParams(request.getParams(), ACTION, NAME, "collections"); } public void testDeleteAlias() { - final CollectionAdminRequest.DeleteAlias request = new CollectionAdminRequest.DeleteAlias() - .setAliasName("name"); + final CollectionAdminRequest.DeleteAlias request = CollectionAdminRequest.deleteAlias("name"); assertContainsParams(request.getParams(), ACTION, NAME); } @@ -175,10 +172,7 @@ public class CollectionAdminRequestRequiredParamsTest extends LuceneTestCase { } public void testMigrate() { - final CollectionAdminRequest.Migrate request = new CollectionAdminRequest.Migrate() - .setCollectionName("collection") - .setTargetCollection("target") - .setSplitKey("splitKey"); + final CollectionAdminRequest.Migrate request = CollectionAdminRequest.migrateData("collection","targer","splitKey"); assertContainsParams(request.getParams(), ACTION, COLLECTION, "target.collection", "split.key"); } @@ -188,10 +182,21 @@ public class CollectionAdminRequestRequiredParamsTest extends LuceneTestCase { } public void testRequestStatus() { - final CollectionAdminRequest.RequestStatus request = new CollectionAdminRequest.RequestStatus() - .setRequestId("request"); + final CollectionAdminRequest.RequestStatus request = CollectionAdminRequest.requestStatus("request"); assertContainsParams(request.getParams(), ACTION, REQUESTID); } + + public void testDeleteStatus() { + assertContainsParams(CollectionAdminRequest.deleteAsyncId("foo").getParams(), + ACTION, REQUESTID); + assertContainsParams(CollectionAdminRequest.deleteAllAsyncIds().getParams(), + ACTION, FLUSH); + } + + public void testForceLeader() { + assertContainsParams(CollectionAdminRequest.forceLeaderElection("foo","bar").getParams(), + ACTION, COLLECTION, SHARD); + } private void assertContainsParams(SolrParams solrParams, String... requiredParams) { final Set requiredParamsSet = Sets.newHashSet(requiredParams); diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCollectionAdminRequest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCollectionAdminRequest.java index c21e523855c..29b273ede87 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCollectionAdminRequest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCollectionAdminRequest.java @@ -17,7 +17,7 @@ package org.apache.solr.client.solrj.request; import org.apache.lucene.util.LuceneTestCase; -import org.apache.solr.client.solrj.request.CollectionAdminRequest.Create; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CollectionAdminRequest.CreateAlias; import org.apache.solr.client.solrj.request.CollectionAdminRequest.CreateShard; import org.apache.solr.common.SolrException; @@ -30,57 +30,57 @@ public class TestCollectionAdminRequest extends LuceneTestCase { @Test public void testInvalidCollectionNameRejectedWhenCreatingCollection() { - final Create createRequest = new Create(); - try { - createRequest.setCollectionName("invalid$collection@name"); - fail(); - } catch (SolrException e) { - final String exceptionMessage = e.getMessage(); - assertTrue(exceptionMessage.contains("Invalid collection")); - assertTrue(exceptionMessage.contains("invalid$collection@name")); - assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); - } + final SolrException e = expectThrows(SolrException.class, () -> { + CollectionAdminRequest.createCollection("invalid$collection@name", null, 1, 1); + }); + final String exceptionMessage = e.getMessage(); + assertTrue(exceptionMessage.contains("Invalid collection")); + assertTrue(exceptionMessage.contains("invalid$collection@name")); + assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); } @Test - public void testInvalidShardNamesRejectedWhenCreatingCollection() { - final Create createRequest = new Create(); - try { - createRequest.setShards("invalid$shard@name"); - fail(); - } catch (SolrException e) { - final String exceptionMessage = e.getMessage(); - assertTrue(exceptionMessage.contains("Invalid shard")); - assertTrue(exceptionMessage.contains("invalid$shard@name")); - assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); - } + public void testInvalidShardNamesRejectedWhenCreatingImplicitCollection() { + final SolrException e = expectThrows(SolrException.class, () -> { + CollectionAdminRequest.createCollectionWithImplicitRouter("fine", "fine", "invalid$shard@name",1,0,0); + }); + final String exceptionMessage = e.getMessage(); + assertTrue(exceptionMessage.contains("Invalid shard")); + assertTrue(exceptionMessage.contains("invalid$shard@name")); + assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); + } + + @Test + public void testInvalidShardNamesRejectedWhenCallingSetShards() { + CollectionAdminRequest.Create request = CollectionAdminRequest.createCollectionWithImplicitRouter("fine",null,"fine",1); + final SolrException e = expectThrows(SolrException.class, () -> { + request.setShards("invalid$shard@name"); + }); + final String exceptionMessage = e.getMessage(); + assertTrue(exceptionMessage.contains("Invalid shard")); + assertTrue(exceptionMessage.contains("invalid$shard@name")); + assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); } @Test public void testInvalidAliasNameRejectedWhenCreatingAlias() { - final CreateAlias createAliasRequest = new CreateAlias(); - try { - createAliasRequest.setAliasName("invalid$alias@name"); - fail(); - } catch (SolrException e) { - final String exceptionMessage = e.getMessage(); - assertTrue(exceptionMessage.contains("Invalid alias")); - assertTrue(exceptionMessage.contains("invalid$alias@name")); - assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); - } + final SolrException e = expectThrows(SolrException.class, () -> { + CreateAlias createAliasRequest = CollectionAdminRequest.createAlias("invalid$alias@name","ignored"); + }); + final String exceptionMessage = e.getMessage(); + assertTrue(exceptionMessage.contains("Invalid alias")); + assertTrue(exceptionMessage.contains("invalid$alias@name")); + assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); } @Test public void testInvalidShardNameRejectedWhenCreatingShard() { - final CreateShard createShardRequest = new CreateShard(); - try { - createShardRequest.setShardName("invalid$shard@name"); - fail(); - } catch (SolrException e) { - final String exceptionMessage = e.getMessage(); - assertTrue(exceptionMessage.contains("Invalid shard")); - assertTrue(exceptionMessage.contains("invalid$shard@name")); - assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); - } + final SolrException e = expectThrows(SolrException.class, () -> { + CreateShard createShardRequest = CollectionAdminRequest.createShard("ignored","invalid$shard@name"); + }); + final String exceptionMessage = e.getMessage(); + assertTrue(exceptionMessage.contains("Invalid shard")); + assertTrue(exceptionMessage.contains("invalid$shard@name")); + assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics")); } } 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 9b8f707157b..2970a8b0e13 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 @@ -1892,8 +1892,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes throws SolrServerException, IOException { CollectionAdminResponse resp = createCollection(testCollectionName, numShards, replicationFactor, maxShardsPerNode); if (resp.getResponse().get("failure") != null) { - CollectionAdminRequest.Delete req = new CollectionAdminRequest.Delete(); - req.setCollectionName(testCollectionName); + CollectionAdminRequest.Delete req = CollectionAdminRequest.deleteCollection(testCollectionName); req.process(cloudClient); resp = createCollection(testCollectionName, numShards, replicationFactor, maxShardsPerNode); @@ -2158,6 +2157,22 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } } + /** + * Logs a WARN if collection can't be deleted, but does not fail or throw an exception + * @return true if success, else false + */ + protected static boolean attemptCollectionDelete(CloudSolrClient client, String collectionName) { + // try to clean up + try { + CollectionAdminRequest.deleteCollection(collectionName).process(client); + return true; + } catch (Exception e) { + // don't fail the test + log.warn("Could not delete collection {} - ignoring", collectionName); + } + return false; + } + protected void logReplicationDetails(Replica replica, StringBuilder builder) throws IOException { try (HttpSolrClient client = new HttpSolrClient.Builder(replica.getCoreUrl()).build()) { ModifiableSolrParams params = new ModifiableSolrParams(); @@ -2203,9 +2218,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } static CollectionAdminResponse getStatusResponse(String requestId, SolrClient client) throws SolrServerException, IOException { - CollectionAdminRequest.RequestStatus requestStatusRequest = new CollectionAdminRequest.RequestStatus(); - requestStatusRequest.setRequestId(requestId); - return requestStatusRequest.process(client); + return CollectionAdminRequest.requestStatus(requestId).process(client); } } From 52c27b4ed309067086d01f5eb272b90982990953 Mon Sep 17 00:00:00 2001 From: Cassandra Targett Date: Wed, 31 May 2017 12:27:00 -0500 Subject: [PATCH 05/11] Ref Guide: fix format issues and inconsistencies --- .../src/format-of-solr-xml.adoc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/solr/solr-ref-guide/src/format-of-solr-xml.adoc b/solr/solr-ref-guide/src/format-of-solr-xml.adoc index 97d6f362bb8..4e55033d2c7 100644 --- a/solr/solr-ref-guide/src/format-of-solr-xml.adoc +++ b/solr/solr-ref-guide/src/format-of-solr-xml.adoc @@ -25,7 +25,7 @@ This section will describe the default `solr.xml` file included with Solr and ho [[Formatofsolr.xml-Definingsolr.xml]] == Defining solr.xml -You can find `solr.xml` in your Solr Home directory or in Zookeeper. The default `solr.xml` file looks like this: +You can find `solr.xml` in your `$SOLR_HOME` directory (usually `server/solr`) in standalone mode or in Zookeeper when using SolrCloud. The default `solr.xml` file looks like this: [source,xml] ---- @@ -66,17 +66,17 @@ There are no attributes that you can specify in the `` tag, which is the r |`collectionsHandler` |As above, for custom CollectionsHandler implementations. | `infoHandler` |As above, for custom InfoHandler implementations. |`coreLoadThreads` |Specifies the number of threads that will be assigned to load cores in parallel. -|`coreRootDirectory` |The root of the core discovery tree, defaults to SOLR_HOME. +|`coreRootDirectory` |The root of the core discovery tree, defaults to `$SOLR_HOME`. |`managementPath` |Currently non-operational. -|`sharedLib` |Specifies the path to a common library directory that will be shared across all cores. Any JAR files in this directory will be added to the search path for Solr plugins. This path is relative to the top-level container's Solr Home. Custom handlers may be placed in this directory +|`sharedLib` |Specifies the path to a common library directory that will be shared across all cores. Any JAR files in this directory will be added to the search path for Solr plugins. This path is relative to `$SOLR_HOME`. Custom handlers may be placed in this directory. |`shareSchema` |This attribute, when set to true, ensures that the multiple cores pointing to the same Schema resource file will be referring to the same IndexSchema Object. Sharing the IndexSchema Object makes loading the core faster. If you use this feature, make sure that no core-specific property is used in your Schema file. |`transientCacheSize` |Defines how many cores with transient=true that can be loaded before swapping the least recently used core for a new core. -|`configSetBaseDir` |The directory under which configsets for solr cores can be found. Defaults to SOLR_HOME/configsets +|`configSetBaseDir` |The directory under which configsets for Solr cores can be found. Defaults to `$SOLR_HOME/configsets`. |=== -==== The `` element +==== The `` Element -This element defines several parameters that relate so SolrCloud. This section is ignored unless the solr instance is started with either `-DzkRun` or `-DzkHost` +This element defines several parameters that relate so SolrCloud. This section is ignored unless theSolr instance is started with either `-DzkRun` or `-DzkHost` // TODO: Change column width to %autowidth.spread when https://github.com/asciidoctor/asciidoctor-pdf/issues/599 is fixed @@ -96,18 +96,18 @@ This element defines several parameters that relate so SolrCloud. This section i |`zkCredentialsProvider` & ` zkACLProvider` |Optional parameters that can be specified if you are using <>. |=== -==== The `` element +==== The `` Element // TODO: Change column width to %autowidth.spread when https://github.com/asciidoctor/asciidoctor-pdf/issues/599 is fixed [cols="30,70",options="header"] |=== |Node |Description -|`class` |The class to use for logging. The corresponding JAR file must be available to solr, perhaps through a `` directive in solrconfig.xml. +|`class` |The class to use for logging. The corresponding JAR file must be available to Solr, perhaps through a `` directive in `solrconfig.xml`. |`enabled` |true/false - whether to enable logging or not. |=== -===== The `` element +===== The `` Element // TODO: Change column width to %autowidth.spread when https://github.com/asciidoctor/asciidoctor-pdf/issues/599 is fixed @@ -118,7 +118,7 @@ This element defines several parameters that relate so SolrCloud. This section i |`threshold` |The logging level above which your particular logging implementation will record. For example when using log4j one might specify DEBUG, WARN, INFO, etc. |=== -==== The `` element +==== The `` Element Custom shard handlers can be defined in `solr.xml` if you wish to create a custom shard handler. @@ -134,8 +134,8 @@ Since this is a custom shard handler, sub-elements are specific to the implement [cols="30,70",options="header"] |=== |Node |Description -|`socketTimeout` |The read timeout for intra-cluster query and administrative requests. The default is the same as the distribUpdateSoTimeout specified in the solrcloud section. -|`connTimeout` |The connection timeout for intra-cluster query and administrative requests. Defaults to the distribUpdateConnTimeout specified in the solrcloud section +|`socketTimeout` |The read timeout for intra-cluster query and administrative requests. The default is the same as the `distribUpdateSoTimeout` specified in the `` section. +|`connTimeout` |The connection timeout for intra-cluster query and administrative requests. Defaults to the `distribUpdateConnTimeout` specified in the `` section |`urlScheme` |URL scheme to be used in distributed search |`maxConnectionsPerHost` |Maximum connections allowed per host. Defaults to 20 |`maxConnections` |Maximum total connections allowed. Defaults to 10000 From d148bd4e9ea7bf3d117cc46b6576f824b79c39d9 Mon Sep 17 00:00:00 2001 From: Cassandra Targett Date: Wed, 31 May 2017 12:27:28 -0500 Subject: [PATCH 06/11] Ref Guide: remove lingering references to "example Jetty" and "your container" --- solr/solr-ref-guide/src/coreadmin-api.adoc | 2 +- solr/solr-ref-guide/src/enabling-ssl.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/solr-ref-guide/src/coreadmin-api.adoc b/solr/solr-ref-guide/src/coreadmin-api.adoc index 3624c52e073..a2e3aa3a0a6 100644 --- a/solr/solr-ref-guide/src/coreadmin-api.adoc +++ b/solr/solr-ref-guide/src/coreadmin-api.adoc @@ -119,7 +119,7 @@ The RELOAD action loads a new core from the configuration of an existing, regist `admin/cores?action=RELOAD&core=_core-name_` -This is useful when you've made changes to a Solr core's configuration on disk, such as adding new field definitions. Calling the RELOAD action lets you apply the new configuration without having to restart the Web container. +This is useful when you've made changes to a Solr core's configuration on disk, such as adding new field definitions. Calling the RELOAD action lets you apply the new configuration without having to restart Solr. [IMPORTANT] ==== diff --git a/solr/solr-ref-guide/src/enabling-ssl.adoc b/solr/solr-ref-guide/src/enabling-ssl.adoc index 87394eef1c9..ec6b59d079c 100644 --- a/solr/solr-ref-guide/src/enabling-ssl.adoc +++ b/solr/solr-ref-guide/src/enabling-ssl.adoc @@ -20,7 +20,7 @@ Solr can encrypt communications to and from clients, and between nodes in SolrCloud mode, with SSL. -This section describes enabling SSL with the example Jetty server using a self-signed certificate. +This section describes enabling SSL using a self-signed certificate. For background on SSL certificates and keys, see http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/. From 872b0dba2d383255ffc020a2b429e395d9817175 Mon Sep 17 00:00:00 2001 From: Mark Miller Date: Wed, 31 May 2017 14:24:18 -0400 Subject: [PATCH 07/11] SOLR-10360: Solr HDFS snapshot export fails due to FileNotFoundException error when using MR1 instead of yarn. This closes #173 --- solr/CHANGES.txt | 3 +++ solr/server/scripts/cloud-scripts/snapshotscli.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 1192d36feda..a2dc8201bcf 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -250,6 +250,9 @@ Bug Fixes * SOLR-10719: Creating a core.properties fails if the parent of core.properties is a symlinked dierctory (Erick Erickson) +* SOLR-10360: Solr HDFS snapshot export fails due to FileNotFoundException error when using MR1 instead of + yarn. (Hrishikesh via Mark Miller) + Optimizations ---------------------- * SOLR-10634: JSON Facet API: When a field/terms facet will retrieve all buckets (i.e. limit:-1) diff --git a/solr/server/scripts/cloud-scripts/snapshotscli.sh b/solr/server/scripts/cloud-scripts/snapshotscli.sh index 41ae4aa0321..f885721f660 100755 --- a/solr/server/scripts/cloud-scripts/snapshotscli.sh +++ b/solr/server/scripts/cloud-scripts/snapshotscli.sh @@ -86,7 +86,7 @@ copy_snapshot_files() { for shardId in $(hdfs dfs -stat "%n" "${copylisting_dir_path}/*"); do oPath="${destPath}/${snapshotName}/snapshot.${shardId}" echo "Copying the index files for ${shardId} to ${oPath}" - ${distCpCmd} -f " ${copylisting_dir_path}/${shardId}" "${oPath}" > /dev/null + ${distCpCmd} -f "${copylisting_dir_path}/${shardId}" "${oPath}" > /dev/null done else echo "Directory ${copylisting_dir_path} does not exist." From 08ea9a787e624db4440c57b882afcfecddecc86b Mon Sep 17 00:00:00 2001 From: Karl Wright Date: Wed, 31 May 2017 15:03:44 -0400 Subject: [PATCH 08/11] LUCENE-7853: Return the public interface, not the private implementation --- .../lucene/spatial3d/geom/GeoPolygonFactory.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java index 4c1850ec06a..7cabe3217e7 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java @@ -56,9 +56,9 @@ public class GeoPolygonFactory { * that we are dealing with a concave polygon, e.g. the polygon has been serialized. * If there is not such certainty, please refer to @{@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List)}. * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. - * @return a GeoConcavePolygon corresponding to what was specified. + * @return a GeoPolygon corresponding to what was specified. */ - public static GeoConcavePolygon makeGeoConcavePolygon(final PlanetModel planetModel, + public static GeoPolygon makeGeoConcavePolygon(final PlanetModel planetModel, final List pointList) { return new GeoConcavePolygon(planetModel, pointList); } @@ -70,9 +70,9 @@ public class GeoPolygonFactory { * there is certainty that we are dealing with a convex polygon, e.g. the polygon has been serialized. * If there is not such certainty, please refer to @{@link GeoPolygonFactory#makeGeoPolygon(PlanetModel, List)}. * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. - * @return a GeoConvexPolygon corresponding to what was specified. + * @return a GeoPolygon corresponding to what was specified. */ - public static GeoConvexPolygon makeGeoConvexPolygon(final PlanetModel planetModel, + public static GeoPolygon makeGeoConvexPolygon(final PlanetModel planetModel, final List pointList) { return new GeoConvexPolygon(planetModel, pointList); } @@ -105,9 +105,9 @@ public class GeoPolygonFactory { * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside * each hole as being "in set". Null == none. - * @return a GeoConcavePolygon corresponding to what was specified. + * @return a GeoPolygon corresponding to what was specified. */ - public static GeoConcavePolygon makeGeoConcavePolygon(final PlanetModel planetModel, + public static GeoPolygon makeGeoConcavePolygon(final PlanetModel planetModel, final List pointList, final List holes) { return new GeoConcavePolygon(planetModel,pointList, holes); @@ -122,9 +122,9 @@ public class GeoPolygonFactory { * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside * each hole as being "in set". Null == none. - * @return a GeoConvexPolygon corresponding to what was specified. + * @return a GeoPolygon corresponding to what was specified. */ - public static GeoConvexPolygon makeGeoConvexPolygon(final PlanetModel planetModel, + public static GeoPolygon makeGeoConvexPolygon(final PlanetModel planetModel, final List pointList, final List holes) { return new GeoConvexPolygon(planetModel,pointList, holes); From 22c2ed070a821efa3c5a81ca03312d4034fcb878 Mon Sep 17 00:00:00 2001 From: Tomas Fernandez Lobbe Date: Wed, 31 May 2017 13:53:34 -0700 Subject: [PATCH 09/11] SOLR-10773: Add support for replica types in V2 API --- .../org/apache/solr/cloud/AddReplicaCmd.java | 3 +- .../apispec/collections.Commands.json | 14 ++- ...ollections.collection.shards.Commands.json | 5 ++ .../apache/solr/cloud/TestPullReplica.java | 89 +++++++++++++++---- .../apache/solr/cloud/TestTlogReplica.java | 86 ++++++++++++++---- .../handler/admin/TestCollectionAPIs.java | 38 +++++++- 6 files changed, 197 insertions(+), 38 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java index 7338d9e645e..63acdd12b9a 100644 --- a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java @@ -22,6 +22,7 @@ import java.lang.invoke.MethodHandles; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import org.apache.commons.lang.StringUtils; @@ -72,7 +73,7 @@ public class AddReplicaCmd implements OverseerCollectionMessageHandler.Cmd { String node = message.getStr(CoreAdminParams.NODE); String shard = message.getStr(SHARD_ID_PROP); String coreName = message.getStr(CoreAdminParams.NAME); - Replica.Type replicaType = Replica.Type.valueOf(message.getStr(ZkStateReader.REPLICA_TYPE, Replica.Type.NRT.name())); + Replica.Type replicaType = Replica.Type.valueOf(message.getStr(ZkStateReader.REPLICA_TYPE, Replica.Type.NRT.name()).toUpperCase(Locale.ROOT)); boolean parallel = message.getBool("parallel", false); if (StringUtils.isBlank(coreName)) { coreName = message.getStr(CoreAdminParams.PROPERTY_PREFIX + CoreAdminParams.NAME); diff --git a/solr/core/src/resources/apispec/collections.Commands.json b/solr/core/src/resources/apispec/collections.Commands.json index 8f5132aaa67..13a75c035cd 100644 --- a/solr/core/src/resources/apispec/collections.Commands.json +++ b/solr/core/src/resources/apispec/collections.Commands.json @@ -51,7 +51,19 @@ }, "replicationFactor": { "type": "integer", - "description": "The number of replicas to be created for each shard. Replicas are physical copies of each shard, acting as failover for the shard." + "description": "The number of NRT replicas to be created for each shard. Replicas are physical copies of each shard, acting as failover for the shard." + }, + "nrtReplicas": { + "type": "integer", + "description": "The number of NRT replicas to be created for each shard. Replicas are physical copies of each shard, acting as failover for the shard. Replicas of type NRT will be updated with each document that is added to the cluster, and can use \"softCommits\" to get a new view of the index in Near Real Time. This parameter works in the same way as 'replicationFactor'" + }, + "tlogReplicas": { + "type": "integer", + "description": "The number of TLOG replicas to be created for each shard. TLOG replicas update their transaction log for every update to the cluster, but only the shard leader updates the local index, other TLOG replicas will use segment replication and copy the latest index files from the leader." + }, + "pullReplicas": { + "type": "integer", + "description": "The number of PULL replicas to be created for each shard. PULL replicas don't receive copies of the documents on update requests, they just replicate the latest segments periodically from the shard leader. PULL replicas can't become shard leaders, and need at least one active TLOG(recommended) or NRT replicas in the shard to replicate from." }, "nodeSet": { "type": "array", diff --git a/solr/core/src/resources/apispec/collections.collection.shards.Commands.json b/solr/core/src/resources/apispec/collections.collection.shards.Commands.json index c3bf7bf83a7..4750e2cb69e 100644 --- a/solr/core/src/resources/apispec/collections.collection.shards.Commands.json +++ b/solr/core/src/resources/apispec/collections.collection.shards.Commands.json @@ -101,6 +101,11 @@ "async": { "type": "string", "description": "Defines a request ID that can be used to track this action after it's submitted. The action will be processed asynchronously when this is defined." + }, + "type": { + "type": "string", + "enum":["NRT", "TLOG", "PULL"], + "description": "The type of replica to add. NRT (default), TLOG or PULL" } }, "required":["shard"] diff --git a/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java b/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java index cb0603df075..2156d3bf0a6 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java @@ -28,8 +28,12 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; @@ -117,21 +121,40 @@ public class TestPullReplica extends SolrCloudTestCase { @Repeat(iterations=2) // 2 times to make sure cleanup is complete and we can create the same collection public void testCreateDelete() throws Exception { try { - if (random().nextBoolean()) { - CollectionAdminRequest.createCollection(collectionName, "conf", 2, 1, 0, 3) - .setMaxShardsPerNode(100) - .process(cluster.getSolrClient()); - } else { - // Sometimes don't use SolrJ. - String url = String.format(Locale.ROOT, "%s/admin/collections?action=CREATE&name=%s&numShards=%s&pullReplicas=%s&maxShardsPerNode=%s", - cluster.getRandomJetty(random()).getBaseUrl(), - collectionName, - 2, // numShards - 3, // pullReplicas - 100); // maxShardsPerNode - url = url + pickRandom("", "&nrtReplicas=1", "&replicationFactor=1"); // These options should all mean the same - HttpGet createCollectionRequest = new HttpGet(url); - cluster.getSolrClient().getHttpClient().execute(createCollectionRequest); + switch (random().nextInt(3)) { + case 0: + // Sometimes use SolrJ + CollectionAdminRequest.createCollection(collectionName, "conf", 2, 1, 0, 3) + .setMaxShardsPerNode(100) + .process(cluster.getSolrClient()); + break; + case 1: + // Sometimes use v1 API + String url = String.format(Locale.ROOT, "%s/admin/collections?action=CREATE&name=%s&numShards=%s&pullReplicas=%s&maxShardsPerNode=%s", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName, + 2, // numShards + 3, // pullReplicas + 100); // maxShardsPerNode + url = url + pickRandom("", "&nrtReplicas=1", "&replicationFactor=1"); // These options should all mean the same + HttpGet createCollectionGet = new HttpGet(url); + cluster.getSolrClient().getHttpClient().execute(createCollectionGet); + break; + case 2: + // Sometimes use V2 API + url = cluster.getRandomJetty(random()).getBaseUrl().toString() + "/____v2/c"; + String requestBody = String.format(Locale.ROOT, "{create:{name:%s, numShards:%s, pullReplicas:%s, maxShardsPerNode:%s %s}}", + collectionName, + 2, // numShards + 3, // pullReplicas + 100, // maxShardsPerNode + pickRandom("", ", nrtReplicas:1", ", replicationFactor:1")); // These options should all mean the same + HttpPost createCollectionPost = new HttpPost(url); + createCollectionPost.setHeader("Content-type", "application/json"); + createCollectionPost.setEntity(new StringEntity(requestBody)); + HttpResponse httpResponse = cluster.getSolrClient().getHttpClient().execute(createCollectionPost); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; } boolean reloaded = false; while (true) { @@ -243,9 +266,9 @@ public class TestPullReplica extends SolrCloudTestCase { DocCollection docCollection = assertNumberOfReplicas(2, 0, 0, false, true); assertEquals(2, docCollection.getSlices().size()); - CollectionAdminRequest.addReplicaToShard(collectionName, "shard1", Replica.Type.PULL).process(cluster.getSolrClient()); + addReplicaToShard("shard1", Replica.Type.PULL); docCollection = assertNumberOfReplicas(2, 0, 1, true, false); - CollectionAdminRequest.addReplicaToShard(collectionName, "shard2", Replica.Type.PULL).process(cluster.getSolrClient()); + addReplicaToShard("shard2", Replica.Type.PULL); docCollection = assertNumberOfReplicas(2, 0, 2, true, false); waitForState("Expecting collection to have 2 shards and 2 replica each", collectionName, clusterShape(2, 2)); @@ -587,4 +610,36 @@ public class TestPullReplica extends SolrCloudTestCase { cluster.getSolrClient().add(collectionName, docs); cluster.getSolrClient().commit(collectionName); } + + private void addReplicaToShard(String shardName, Replica.Type type) throws ClientProtocolException, IOException, SolrServerException { + switch (random().nextInt(3)) { + case 0: // Add replica with SolrJ + CollectionAdminResponse response = CollectionAdminRequest.addReplicaToShard(collectionName, shardName, type).process(cluster.getSolrClient()); + assertEquals("Unexpected response status: " + response.getStatus(), 0, response.getStatus()); + break; + case 1: // Add replica with V1 API + String url = String.format(Locale.ROOT, "%s/admin/collections?action=ADDREPLICA&collection=%s&shard=%s&type=%s", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName, + shardName, + type); + HttpGet addReplicaGet = new HttpGet(url); + HttpResponse httpResponse = cluster.getSolrClient().getHttpClient().execute(addReplicaGet); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; + case 2:// Add replica with V2 API + url = String.format(Locale.ROOT, "%s/____v2/c/%s/shards", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName); + String requestBody = String.format(Locale.ROOT, "{add-replica:{shard:%s, type:%s}}", + shardName, + type); + HttpPost addReplicaPost = new HttpPost(url); + addReplicaPost.setHeader("Content-type", "application/json"); + addReplicaPost.setEntity(new StringEntity(requestBody)); + httpResponse = cluster.getSolrClient().getHttpClient().execute(addReplicaPost); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; + } + } } diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java b/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java index 1c2e7aa6d2e..999060144dc 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestTlogReplica.java @@ -29,8 +29,12 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.client.solrj.SolrClient; @@ -145,20 +149,38 @@ public class TestTlogReplica extends SolrCloudTestCase { @Repeat(iterations=2) // 2 times to make sure cleanup is complete and we can create the same collection public void testCreateDelete() throws Exception { try { - if (random().nextBoolean()) { - CollectionAdminRequest.createCollection(collectionName, "conf", 2, 0, 4, 0) - .setMaxShardsPerNode(100) - .process(cluster.getSolrClient()); - } else { - // Sometimes don't use SolrJ - String url = String.format(Locale.ROOT, "%s/admin/collections?action=CREATE&name=%s&numShards=%s&tlogReplicas=%s&maxShardsPerNode=%s", - cluster.getRandomJetty(random()).getBaseUrl(), - collectionName, - 2, // numShards - 4, // tlogReplicas - 100); // maxShardsPerNode - HttpGet createCollectionRequest = new HttpGet(url); - cluster.getSolrClient().getHttpClient().execute(createCollectionRequest); + switch (random().nextInt(3)) { + case 0: + CollectionAdminRequest.createCollection(collectionName, "conf", 2, 0, 4, 0) + .setMaxShardsPerNode(100) + .process(cluster.getSolrClient()); + break; + case 1: + // Sometimes don't use SolrJ + String url = String.format(Locale.ROOT, "%s/admin/collections?action=CREATE&name=%s&numShards=%s&tlogReplicas=%s&maxShardsPerNode=%s", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName, + 2, // numShards + 4, // tlogReplicas + 100); // maxShardsPerNode + HttpGet createCollectionGet = new HttpGet(url); + HttpResponse httpResponse = cluster.getSolrClient().getHttpClient().execute(createCollectionGet); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; + case 2: + // Sometimes use V2 API + url = cluster.getRandomJetty(random()).getBaseUrl().toString() + "/____v2/c"; + String requestBody = String.format(Locale.ROOT, "{create:{name:%s, numShards:%s, tlogReplicas:%s, maxShardsPerNode:%s}}", + collectionName, + 2, // numShards + 4, // tlogReplicas + 100); // maxShardsPerNode + HttpPost createCollectionPost = new HttpPost(url); + createCollectionPost.setHeader("Content-type", "application/json"); + createCollectionPost.setEntity(new StringEntity(requestBody)); + httpResponse = cluster.getSolrClient().getHttpClient().execute(createCollectionPost); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; } boolean reloaded = false; @@ -244,9 +266,9 @@ public class TestTlogReplica extends SolrCloudTestCase { DocCollection docCollection = createAndWaitForCollection(2, 0, 1, 0); assertEquals(2, docCollection.getSlices().size()); - CollectionAdminRequest.addReplicaToShard(collectionName, "shard1", Replica.Type.TLOG).process(cluster.getSolrClient()); + addReplicaToShard("shard1", Replica.Type.TLOG); docCollection = assertNumberOfReplicas(0, 3, 0, true, false); - CollectionAdminRequest.addReplicaToShard(collectionName, "shard2", Replica.Type.TLOG).process(cluster.getSolrClient()); + addReplicaToShard("shard2", Replica.Type.TLOG); docCollection = assertNumberOfReplicas(0, 4, 0, true, false); waitForState("Expecting collection to have 2 shards and 2 replica each", collectionName, clusterShape(2, 2)); @@ -260,6 +282,38 @@ public class TestTlogReplica extends SolrCloudTestCase { assertNumberOfReplicas(0, 3, 0, true, true); } + private void addReplicaToShard(String shardName, Replica.Type type) throws ClientProtocolException, IOException, SolrServerException { + switch (random().nextInt(3)) { + case 0: // Add replica with SolrJ + CollectionAdminResponse response = CollectionAdminRequest.addReplicaToShard(collectionName, shardName, type).process(cluster.getSolrClient()); + assertEquals("Unexpected response status: " + response.getStatus(), 0, response.getStatus()); + break; + case 1: // Add replica with V1 API + String url = String.format(Locale.ROOT, "%s/admin/collections?action=ADDREPLICA&collection=%s&shard=%s&type=%s", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName, + shardName, + type); + HttpGet addReplicaGet = new HttpGet(url); + HttpResponse httpResponse = cluster.getSolrClient().getHttpClient().execute(addReplicaGet); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; + case 2:// Add replica with V2 API + url = String.format(Locale.ROOT, "%s/____v2/c/%s/shards", + cluster.getRandomJetty(random()).getBaseUrl(), + collectionName); + String requestBody = String.format(Locale.ROOT, "{add-replica:{shard:%s, type:%s}}", + shardName, + type); + HttpPost addReplicaPost = new HttpPost(url); + addReplicaPost.setHeader("Content-type", "application/json"); + addReplicaPost.setEntity(new StringEntity(requestBody)); + httpResponse = cluster.getSolrClient().getHttpClient().execute(addReplicaPost); + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + break; + } + } + public void testRemoveLeader() throws Exception { doReplaceLeader(true); } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java index 9f5a2461a7c..e7dbf3ea9f8 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java @@ -58,11 +58,19 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 { MockCollectionsHandler collectionsHandler = new MockCollectionsHandler(); ApiBag apiBag = new ApiBag(false); Collection apis = collectionsHandler.getApis(); - for (Api api : apis) apiBag.register(api, Collections.EMPTY_MAP); + for (Api api : apis) apiBag.register(api, Collections.emptyMap()); //test a simple create collection call compareOutput(apiBag, "/collections", POST, "{create:{name:'newcoll', config:'schemaless', numShards:2, replicationFactor:2 }}", null, "{name:newcoll, fromApi:'true', replicationFactor:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}"); + + compareOutput(apiBag, "/collections", POST, + "{create:{name:'newcoll', config:'schemaless', numShards:2, nrtReplicas:2 }}", null, + "{name:newcoll, fromApi:'true', nrtReplicas:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}"); + + compareOutput(apiBag, "/collections", POST, + "{create:{name:'newcoll', config:'schemaless', numShards:2, nrtReplicas:2, tlogReplicas:2, pullReplicas:2 }}", null, + "{name:newcoll, fromApi:'true', nrtReplicas:'2', tlogReplicas:'2', pullReplicas:'2', collection.configName:schemaless, numShards:'2', stateFormat:'2', operation:create}"); //test a create collection with custom properties compareOutput(apiBag, "/collections", POST, @@ -106,6 +114,21 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 { "{split:{ splitKey:id12345, coreProperties : {prop1:prop1Val, prop2:prop2Val} }}", null, "{collection: collName , split.key : id12345 , operation : splitshard, property.prop1:prop1Val, property.prop2: prop2Val}" ); + + compareOutput(apiBag, "/collections/collName/shards", POST, + "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'TLOG' }}", null, + "{collection: collName , shard : shard1, node :'localhost_8978', operation : addreplica, type: TLOG}" + ); + + compareOutput(apiBag, "/collections/collName/shards", POST, + "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'PULL' }}", null, + "{collection: collName , shard : shard1, node :'localhost_8978', operation : addreplica, type: PULL}" + ); + + assertErrorContains(apiBag, "/collections/collName/shards", POST, + "{add-replica:{shard: shard1, node: 'localhost_8978' , type:'foo' }}", null, + "Value of enum must be one of" + ); compareOutput(apiBag, "/collections/collName", POST, "{add-replica-property : {name:propA , value: VALA, shard: shard1, replica:replica1}}", null, @@ -150,13 +173,22 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 { Map expected = (Map) fromJSONString(expectedOutputMapJson); assertMapEqual(expected, output); return output; - + } + + static void assertErrorContains(final ApiBag apiBag, final String path, final SolrRequest.METHOD method, + final String payload, final CoreContainer cc, String expectedErrorMsg) throws Exception { + try { + makeCall(apiBag, path, method, payload, cc); + fail("Expected exception"); + } catch (RuntimeException e) { + assertTrue("Expected exception with error message '" + expectedErrorMsg + "' but got: " + e.getMessage(), e.getMessage().contains(expectedErrorMsg)); + } } public static Pair makeCall(final ApiBag apiBag, String path, final SolrRequest.METHOD method, final String payload, final CoreContainer cc) throws Exception { - SolrParams queryParams = new MultiMapSolrParams(Collections.EMPTY_MAP); + SolrParams queryParams = new MultiMapSolrParams(Collections.emptyMap()); if (path.indexOf('?') > 0) { String queryStr = path.substring(path.indexOf('?') + 1); path = path.substring(0, path.indexOf('?')); From f34155fb2014393da50a836a1b78416c406b0dfd Mon Sep 17 00:00:00 2001 From: Cassandra Targett Date: Wed, 31 May 2017 16:08:09 -0500 Subject: [PATCH 10/11] SOLR-10290: Replace the bright green in the bottom nav links with a lighter tone of the header --- solr/solr-ref-guide/src/css/theme-solr.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/solr-ref-guide/src/css/theme-solr.css b/solr/solr-ref-guide/src/css/theme-solr.css index ae0d6bf2f2f..daa8fbef607 100644 --- a/solr/solr-ref-guide/src/css/theme-solr.css +++ b/solr/solr-ref-guide/src/css/theme-solr.css @@ -55,7 +55,7 @@ a[data-toggle="tooltip"] { /* Used for nav buttons */ .btn-primary { color: #ffffff; - background-color: #0A7C38; + background-color: #F35B38; border-color: #E6E7E8; } From 7da9e9d7352083060d45c1a10430a3a17fdeefbe Mon Sep 17 00:00:00 2001 From: Mark Miller Date: Wed, 31 May 2017 17:44:00 -0400 Subject: [PATCH 11/11] SOLR-10137: Ensure that ConfigSets created via API are mutable. --- solr/CHANGES.txt | 2 ++ .../java/org/apache/solr/handler/admin/ConfigSetsHandler.java | 4 ++++ .../test/org/apache/solr/handler/admin/TestConfigsApi.java | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a2dc8201bcf..98f3ec2769d 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -252,6 +252,8 @@ Bug Fixes * SOLR-10360: Solr HDFS snapshot export fails due to FileNotFoundException error when using MR1 instead of yarn. (Hrishikesh via Mark Miller) + +* SOLR-10137: Ensure that ConfigSets created via API are mutable. (Hrishikesh via Mark Miller) Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java index 3f857e79d67..34313d00d89 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java @@ -238,6 +238,10 @@ public class ConfigSetsHandler extends RequestHandlerBase implements PermissionN props.put(param, params.get(param)); } } + + // The configset created via an API should be mutable. + props.put("immutable", "false"); + return props; } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/TestConfigsApi.java b/solr/core/src/test/org/apache/solr/handler/admin/TestConfigsApi.java index d2c96a66be2..c0c193de872 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/TestConfigsApi.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/TestConfigsApi.java @@ -54,6 +54,6 @@ public class TestConfigsApi extends SolrTestCaseJ4 { "{name :sample, operation:delete}"); compareOutput(apiBag, "/cluster/configs", POST, "{create:{name : newconf, baseConfigSet: sample }}", null, - "{operation:create, name :newconf, baseConfigSet: sample }"); + "{operation:create, name :newconf, baseConfigSet: sample, immutable: false }"); } }