Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions solr/core/src/java/org/apache/solr/api/V2HttpCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public class V2HttpCall extends HttpSolrCall {
private boolean servedByJaxRs =
false; // A flag indicating whether the request was served by JAX-RS or the native framework
HashMap<String, String> parts = new HashMap<>();
static final Set<String> knownPrefixes = Set.of("cluster", "node", "collections", "cores", "c");
static final Set<String> knownPrefixes =
Set.of("cluster", "node", "collections", "cores", "coll");

public V2HttpCall(
SolrDispatchFilter solrDispatchFilter,
Expand Down Expand Up @@ -134,7 +135,7 @@ public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
assert core == null;
}

if (pathSegments.size() > 1 && ("c".equals(prefix) || "collections".equals(prefix))) {
if (pathSegments.size() > 1 && ("coll".equals(prefix) || "collections".equals(prefix))) {
origCorename = pathSegments.get(1);

String collectionStr = queryParams.get(COLLECTION_PROP, origCorename);
Expand Down Expand Up @@ -169,7 +170,7 @@ public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
extractRemotePath(collectionName);
if (action == REMOTEPROXY) {
action = ADMIN_OR_REMOTEPROXY;
coreUrl = coreUrl.replace("/solr/", "/solr/____v2/c/");
coreUrl = coreUrl.replace("/solr/", "/solr/____v2/coll/");
normalizeAndSetPath(path.substring(prefix.length() + collectionName.length() + 2));
path = this.path;
return;
Expand Down Expand Up @@ -473,7 +474,7 @@ protected void populateTracingSpan(Span span) {
}
TraceUtils.setDbInstance(span, coreOrColName);

// Get the templatize-ed path, ex: "/c/{collection}"
// Get the templatize-ed path, ex: "/coll/{collection}"
final String path = computeEndpointPath();
final String verb = req.getMethod().toLowerCase(Locale.ROOT);
span.updateName(verb + ":" + path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* @see MigrateDocsPayload
*/
@EndPoint(
path = {"/c/{collection}", "/collections/{collection}"},
path = {"/coll/{collection}", "/collections/{collection}"},
method = POST,
permission = COLL_EDIT_PERM)
public class MigrateDocsAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* @see ModifyCollectionPayload
*/
@EndPoint(
path = {"/c/{collection}", "/collections/{collection}"},
path = {"/coll/{collection}", "/collections/{collection}"},
method = POST,
permission = COLL_EDIT_PERM)
public class ModifyCollectionAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* @see MoveReplicaPayload
*/
@EndPoint(
path = {"/c/{collection}", "/collections/{collection}"},
path = {"/coll/{collection}", "/collections/{collection}"},
method = POST,
permission = COLL_EDIT_PERM)
public class MoveReplicaAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* @see RebalanceLeadersPayload
*/
@EndPoint(
path = {"/c/{collection}", "/collections/{collection}"},
path = {"/coll/{collection}", "/collections/{collection}"},
method = POST,
permission = COLL_EDIT_PERM)
public class RebalanceLeadersAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* @see SplitShardPayload
*/
@EndPoint(
path = {"/c/{collection}/shards", "/collections/{collection}/shards"},
path = {"/coll/{collection}/shards", "/collections/{collection}/shards"},
method = POST,
permission = COLL_EDIT_PERM)
public class SplitShardAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private void setupHarnesses() {
new RestTestHarness(() -> jettySolrRunner.getBaseUrl().toString() + "/" + COLL_NAME);
if (random().nextBoolean()) {
harness.setServerProvider(
() -> jettySolrRunner.getBaseUrl().toString() + "/____v2/c/" + COLL_NAME);
() -> jettySolrRunner.getBaseUrl().toString() + "/____v2/coll/" + COLL_NAME);
}
restTestHarnesses.add(harness);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ private void testException(

@Test
public void testException() {
String notFoundPath = "/c/" + COLL_NAME + "/abccdef";
String notFoundPath = "/coll/" + COLL_NAME + "/abccdef";
String incorrectPayload = "{rebalance-leaders: {maxAtOnce: abc, maxWaitSeconds: xyz}}";
testException(new XMLResponseParser(), 404, notFoundPath, incorrectPayload);
testException(new JsonMapResponseParser(), 404, notFoundPath, incorrectPayload);
testException(new JavaBinResponseParser(), 404, notFoundPath, incorrectPayload);
testException(new XMLResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
testException(new JavaBinResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
testException(new JsonMapResponseParser(), 400, "/c/" + COLL_NAME, incorrectPayload);
testException(new XMLResponseParser(), 400, "/coll/" + COLL_NAME, incorrectPayload);
testException(new JavaBinResponseParser(), 400, "/coll/" + COLL_NAME, incorrectPayload);
testException(new JsonMapResponseParser(), 400, "/coll/" + COLL_NAME, incorrectPayload);
}

@Test
Expand All @@ -104,14 +104,16 @@ public void testIntrospect() throws Exception {
Map<?, ?> result =
resAsMap(
cluster.getSolrClient(),
new V2Request.Builder("/c/" + COLL_NAME + "/_introspect").withParams(params).build());
new V2Request.Builder("/coll/" + COLL_NAME + "/_introspect")
.withParams(params)
.build());
assertEquals(
"Command not found!", Utils.getObjectByPath(result, false, "/spec[0]/commands/XXXX"));
}

@Test
public void testInvalidWTParamReturnsError() throws Exception {
V2Request request = new V2Request.Builder("/c/" + COLL_NAME + "/get/_introspect").build();
V2Request request = new V2Request.Builder("/coll/" + COLL_NAME + "/get/_introspect").build();
// Using an invalid wt parameter should return a 400 error
request.setResponseParser(new InputStreamResponseParser("bleh"));
NamedList<Object> res = cluster.getSolrClient().request(request);
Expand All @@ -127,16 +129,17 @@ public void testInvalidWTParamReturnsError() throws Exception {
@Test
public void testWTParam() throws Exception {
// When no response parser is set, the default JSON writer should be used
V2Request request = new V2Request.Builder("/c/" + COLL_NAME + "/get/_introspect").build();
V2Request request = new V2Request.Builder("/coll/" + COLL_NAME + "/get/_introspect").build();
request.setResponseParser(null);
Map<?, ?> resp = resAsMap(cluster.getSolrClient(), request);
String respString = resp.toString();

assertFalse(respString.contains("400"));
assertFalse(
respString.contains(
"<p>Problem accessing /solr/____v2/c/collection1/get/_introspect. Reason:"));
assertEquals("/c/collection1/get", Utils.getObjectByPath(resp, true, "/spec[0]/url/paths[0]"));
"<p>Problem accessing /solr/____v2/coll/collection1/get/_introspect. Reason:"));
assertEquals(
"/coll/collection1/get", Utils.getObjectByPath(resp, true, "/spec[0]/url/paths[0]"));
assertEquals(respString, 0, Utils.getObjectByPath(resp, true, "/responseHeader/status"));
}

Expand Down Expand Up @@ -191,7 +194,7 @@ public void testSingleWarning() throws Exception {
NamedList<?> resp =
cluster
.getSolrClient()
.request(new V2Request.Builder("/c/" + COLL_NAME + "/_introspect").build());
.request(new V2Request.Builder("/coll/" + COLL_NAME + "/_introspect").build());
List<?> warnings = resp.getAll("WARNING");
assertEquals(1, warnings.size());
}
Expand Down Expand Up @@ -220,11 +223,11 @@ public void testSetPropertyValidationOfCluster() throws IOException, SolrServerE
@Test
public void testCollectionsApi() throws Exception {
CloudSolrClient client = cluster.getSolrClient();
V2Request req1 = new V2Request.Builder("/c/" + COLL_NAME + "/get/_introspect").build();
V2Request req1 = new V2Request.Builder("/coll/" + COLL_NAME + "/get/_introspect").build();
assertEquals(COLL_NAME, req1.getCollection());
Map<?, ?> result = resAsMap(client, req1);
assertEquals(
"/c/collection1/get", Utils.getObjectByPath(result, true, "/spec[0]/url/paths[0]"));
"/coll/collection1/get", Utils.getObjectByPath(result, true, "/spec[0]/url/paths[0]"));
result =
resAsMap(
client,
Expand All @@ -249,7 +252,7 @@ public void testCollectionsApi() throws Exception {
public void testSelect() throws Exception {
CloudSolrClient cloudClient = cluster.getSolrClient();
final V2Response v2Response =
new V2Request.Builder("/c/" + COLL_NAME + "/select")
new V2Request.Builder("/coll/" + COLL_NAME + "/select")
.withMethod(SolrRequest.METHOD.GET)
.withParams(params("q", "-*:*"))
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

/**
* Unit tests for the V2 APIs found in {@link org.apache.solr.handler.admin.api} that use the
* /c/{collection} path.
* /coll/{collection} path.
*
* <p>This test bears many similarities to {@link TestCollectionAPIs} which appears to test the
* mappings indirectly by checking message sent to the ZK overseer (which is similar, but not
Expand Down
4 changes: 2 additions & 2 deletions solr/core/src/test/org/apache/solr/pkg/TestPackages.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ public void testPluginLoading() throws Exception {
plugins.put("create-expressible", p);

V2Request v2r =
new V2Request.Builder("/c/" + COLLECTION_NAME + "/config")
new V2Request.Builder("/coll/" + COLLECTION_NAME + "/config")
.withMethod(SolrRequest.METHOD.POST)
.withPayload(plugins)
.forceV2(true)
Expand Down Expand Up @@ -501,7 +501,7 @@ public RequestWriter.ContentWriter getContentWriter(String expectedType) {
plugins.put("create-queryparser", p);

v2r =
new V2Request.Builder("/c/" + COLLECTION_NAME + "/config")
new V2Request.Builder("/coll/" + COLLECTION_NAME + "/config")
.withMethod(SolrRequest.METHOD.POST)
.withPayload(plugins)
.forceV2(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public void testV2Api() throws Exception {
assertEquals("post:/collections/{collection}/reload", finishedSpans.get(0).getName());
assertCollectionName(finishedSpans.get(0), COLLECTION);

new V2Request.Builder("/c/" + COLLECTION + "/update/json")
new V2Request.Builder("/coll/" + COLLECTION + "/update/json")
.withMethod(SolrRequest.METHOD.POST)
.withPayload("{\n" + " \"id\" : \"9\"\n" + "}")
.withParams(params("commit", "true"))
Expand All @@ -170,7 +170,7 @@ public void testV2Api() throws Exception {
assertCollectionName(finishedSpans.get(0), COLLECTION);

final V2Response v2Response =
new V2Request.Builder("/c/" + COLLECTION + "/select")
new V2Request.Builder("/coll/" + COLLECTION + "/select")
.withMethod(SolrRequest.METHOD.GET)
.withParams(params("q", "id:9"))
.build()
Expand Down
42 changes: 21 additions & 21 deletions solr/solr-ref-guide/modules/configuration-guide/pages/v2-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ Following are some v2 API URL paths and path prefixes, along with some of the op
|===
|Path prefix |Some Supported Operations
|`/api/collections` |Create, alias, backup, and restore a collection.
|`/api/c/_collection-name_/update` |Update requests.
|`/api/c/_collection-name_/config` |Configuration requests.
|`/api/c/_collection-name_/schema` |Schema requests.
|`/api/c/_collection-name_/_handler-name_` |Handler-specific requests.
|`/api/c/_collection-name_/shards` |Split a shard, create a shard, add a replica.
|`/api/c/_collection-name_/shards/_shard-name_` |Delete a shard, force leader election
|`/api/c/_collection-name_/shards/_shard-name_/_replica-name_` |Delete a replica.
|`/api/coll/_collection-name_/update` |Update requests.
|`/api/coll/_collection-name_/config` |Configuration requests.
|`/api/coll/_collection-name_/schema` |Schema requests.
|`/api/coll/_collection-name_/_handler-name_` |Handler-specific requests.
|`/api/coll/_collection-name_/shards` |Split a shard, create a shard, add a replica.
|`/api/coll/_collection-name_/shards/_shard-name_` |Delete a shard, force leader election
|`/api/coll/_collection-name_/shards/_shard-name_/_replica-name_` |Delete a replica.
|`/api/cores` |Create a core.
|`/api/cores/_core-name_` |Reload, rename, delete, and unload a core.
|`/api/node` |Perform overseer operation, rejoin leader election.
Expand All @@ -57,20 +57,20 @@ Following are some v2 API URL paths and path prefixes, along with some of the op

Append `/_introspect` to any valid v2 API path and the API specification will be returned in JSON format.

`\http://localhost:8983/api/c/_introspect`
`\http://localhost:8983/api/coll/_introspect`

To limit the introspect output to include just one particular HTTP method, add the request parameter `method` with value `GET`, `POST`, or `DELETE`.

`\http://localhost:8983/api/c/_introspect?method=POST`
`\http://localhost:8983/api/coll/_introspect?method=POST`

Most endpoints support commands provided in a body sent via POST.
To limit the introspect output to only one command, add the request parameter `command=_command-name_`.

`\http://localhost:8983/api/c/gettingstarted/_introspect?method=POST&command=modify`
`\http://localhost:8983/api/coll/gettingstarted/_introspect?method=POST&command=modify`

=== Interpreting the Introspect Output

Example: `\http://localhost:8983/api/c/gettingstarted/get/_introspect`
Example: `\http://localhost:8983/api/coll/gettingstarted/get/_introspect`

[source,json]
----
Expand All @@ -80,7 +80,7 @@ Example: `\http://localhost:8983/api/c/gettingstarted/get/_introspect`
"description":"RealTime Get allows retrieving documents by ID before the documents have been committed to the index. It is useful when you need access to documents as soon as they are indexed but your commit times are high for other reasons.",
"methods":["GET"],
"url":{
"paths":["/c/gettingstarted/get"],
"paths":["/coll/gettingstarted/get"],
"params":{
"id":{
"type":"string",
Expand All @@ -105,7 +105,7 @@ Description of some of the keys in the above example:
* `**spec/url/params**`: List of supported URL request params
* `**availableSubPaths**`: List of valid URL subpaths and the HTTP method(s) each supports

Example of introspect for a POST API: `\http://localhost:8983/api/c/gettingstarted/_introspect?method=POST&command=modify`
Example of introspect for a POST API: `\http://localhost:8983/api/coll/gettingstarted/_introspect?method=POST&command=modify`

[source,json]
----
Expand All @@ -115,7 +115,7 @@ Example of introspect for a POST API: `\http://localhost:8983/api/c/gettingstart
"description":"Several collection-level operations are supported with this endpoint: modify collection attributes; reload a collection; migrate documents to a different collection; rebalance collection leaders; balance properties across shards; and add or delete a replica property.",
"methods":["POST"],
"url":{"paths":["/collections/{collection}",
"/c/{collection}"]},
"/coll/{collection}"]},
"commands":{"modify":{
"documentation":"https://solr.apache.org/guide/solr/latest/deployment-guide/collection-management.html#modifycollection",
"description":"Modifies specific attributes of a collection. Multiple attributes can be changed at one time.",
Expand All @@ -126,12 +126,12 @@ Example of introspect for a POST API: `\http://localhost:8983/api/c/gettingstart
"description":"The number of replicas to be created for each shard. Replicas are physical copies of each shard, acting as failover for the shard. Note that changing this value on an existing collection does not automatically add more replicas to the collection. However, it will allow add-replica commands to succeed."}}}}}],
"WARNING":"This response format is experimental. It is likely to change in the future.",
"availableSubPaths":{
"/c/gettingstarted/select":["POST", "GET"],
"/c/gettingstarted/config":["POST", "GET"],
"/c/gettingstarted/schema":["POST", "GET"],
"/c/gettingstarted/export":["POST", "GET"],
"/c/gettingstarted/admin/ping":["POST", "GET"],
"/c/gettingstarted/update":["POST"]}
"/coll/gettingstarted/select":["POST", "GET"],
"/coll/gettingstarted/config":["POST", "GET"],
"/coll/gettingstarted/schema":["POST", "GET"],
"/coll/gettingstarted/export":["POST", "GET"],
"/coll/gettingstarted/admin/ping":["POST", "GET"],
"/coll/gettingstarted/update":["POST"]}
}
----

Expand All @@ -144,7 +144,7 @@ For the "gettingstarted" collection, set the replication factor and whether to a

[source,bash]
----
$ curl http://localhost:8983/api/c/gettingstarted -H 'Content-type:application/json' -d '
$ curl http://localhost:8983/api/coll/gettingstarted -H 'Content-type:application/json' -d '
{ modify: { replicationFactor: "3" } }'

{"responseHeader":{"status":0,"QTime":842}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
public class V2Request extends SolrRequest<V2Response> implements MapWriter {
// only for debugging purposes
public static final ThreadLocal<AtomicLong> v2Calls = new ThreadLocal<>();
static final Pattern COLL_REQ_PATTERN = Pattern.compile("/(c|collections)/([^/]+)/(?!shards)");
static final Pattern COLL_REQ_PATTERN = Pattern.compile("/(coll|collections)/([^/]+)/(?!shards)");
private Object payload;
private SolrParams solrParams;
public final boolean useBinary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ public void testIsCollectionRequest() {
assertFalse(new V2Request.Builder("/collections/a/shards/").build().isPerCollectionRequest());
assertTrue(new V2Request.Builder("/collections/a/update").build().isPerCollectionRequest());
assertEquals("a", new V2Request.Builder("/collections/a/update").build().getCollection());
assertTrue(new V2Request.Builder("/c/a/update").build().isPerCollectionRequest());
assertTrue(new V2Request.Builder("/c/a/schema").build().isPerCollectionRequest());
assertFalse(new V2Request.Builder("/c/a").build().isPerCollectionRequest());
assertTrue(new V2Request.Builder("/coll/a/update").build().isPerCollectionRequest());
assertTrue(new V2Request.Builder("/coll/a/schema").build().isPerCollectionRequest());
assertFalse(new V2Request.Builder("/coll/a").build().isPerCollectionRequest());
}

@Test
Expand Down Expand Up @@ -113,7 +113,7 @@ private void doTest(SolrClient client) throws IOException, SolrServerException {
String requestHandlerName = "/x" + random().nextInt();
assertSuccess(
client,
new V2Request.Builder("/c/test/config")
new V2Request.Builder("/coll/test/config")
.withMethod(SolrRequest.METHOD.POST)
.withPayload(
"{'create-requesthandler' : { 'name' : '"
Expand Down Expand Up @@ -158,7 +158,7 @@ public void testV2Forwarding() throws Exception {

String testServer = cluster.getZkStateReader().getBaseUrlForNodeName(testNode[0]);
V2Request v2r =
new V2Request.Builder("/c/v2forward/_introspect")
new V2Request.Builder("/coll/v2forward/_introspect")
.withMethod(SolrRequest.METHOD.GET)
.build();

Expand Down