Skip to content

SOLR-18450: Relocate GET /api/cluster under /api/collections and return only the collections tree - #4952

Merged
epugh merged 7 commits into
apache:mainfrom
iprithv:SOLR-18450-cluster-status-v2
Oct 6, 2026
Merged

epugh merged 7 commits into
apache:mainfrom
iprithv:SOLR-18450-cluster-status-v2

Conversation

@iprithv

@iprithv iprithv commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

https://issues.apache.org/jira/browse/SOLR-18450

GET /api/cluster is a typed jax-rs api now. with no params it still returns every collection, under cluster.collections. shards, replicas, health, config name, and the usual replica fields (node_name, base_url, core, type, leader) are typed. the rest of the state.json fields stay too: router, replica counts, user properties, and per-replica state when prs=true. leader is still the string "true", same as state.json.

live nodes, the alias map, and cluster properties are off this payload. those live on GET /api/cluster/nodes, GET /api/aliases, and GET /api/cluster/properties. includeall, livenodes, aliases, and clusterproperties are ignored if a caller still sends them. collection, shard, and route still narrow the tree.

each collection still lists the aliases that point at it, since the collections screen shows that list.

v1 clusterstatus is unchanged, and includeall still defaults to true. POST /api/cluster is unchanged.

@github-actions github-actions Bot added documentation Improvements or additions to documentation admin-ui tests cat:api labels Sep 26, 2026
* V2 API definition for the collections, shards, and replicas tree.
*
* <p>This API ({@code GET /api/cluster}) returns the same collection tree as v1 {@code
* CLUSTERSTATUS}. It does not return live nodes, the alias map, or cluster properties. With no

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess this comment about what it doesn't do is fine as we wait to get rid of v1...

@iprithv
iprithv force-pushed the SOLR-18450-cluster-status-v2 branch from 2e8e327 to d076904 Compare September 26, 2026 23:37

@epugh epugh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great progress!


@Schema(
description =
"Cluster geometry. Does not include live nodes, the alias map, or cluster properties.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we don't need the the Does Not aspects in the descritiption. We highlight that int he docs..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, trimmed wording here.

recordCollectionForLogAndTracing(collection, solrQueryRequest);
}

// Only the parameters this API documents. includeAll, liveNodes, aliases, and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, not sure we should still be documenting the includeAll and liveNodes etc at this level. One comment, okay, but seems like too many

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if you pass them in? does it get run?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we returned HTTP 400 for all unknown / unsupported params. Since a caller asking for live_nodes won’t get them, so fail fast.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, not sure we should still be documenting the includeAll and liveNodes etc at this level. One comment, okay, but seems like too many

shortened that to one line. those params are still ignored if someone sends them.. we only bind collection, shard, route, and prs.

what happens if you pass them in? does it get run?

so they are ignored. the handler builds a fresh param set from the documented query params only, so liveNodes / aliases / clusterProperties / includeAll never reach ClusterStatus.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we returned HTTP 400 for all unknown / unsupported params. Since a caller asking for live_nodes won’t get them, so fail fast.

i’d like that too as a broader jersey/v2 convention :) but i’m leaving it out of this PR. we already walked back a bare-GET 400 because solr-operator and the admin UI both need the full tree with no selector. rejecting the old v1 knobs here would be a one-off, and random undeclared query params are ignored by jersey today the same way. happy to do a follow-up that fails unknown params more widely if we want that policy :)

// Resolve the collection list now so a missing name fails the request, rather than during
// response writing. The per-collection JSON is still built while the response is written.
PreparedCollections prepared = prepareCollections(aliases);
if (solrVersion == null || solrVersion.greaterThanOrEqualTo(SolrVersion.valueOf("9.9.0"))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh.... is this part of a rolling upgrade feature?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thsi is pre-existing, from SOLR-17582.. it streams collections as a MapWriter for SolrJ 9.9+, and falls back to a NamedList for older clients. not a rolling-upgrade feature of this change... just left that path alone.

return req;
}

@EndPoint(method = GET, path = "/cluster", permission = COLL_READ_PERM)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there also a registerV2 Api method on this guy which can be removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no registerV2 on this class :) only removed old GET /cluster @ EndPoint that forwarded to v1 CLUSTERSTATUS. kept POST /cluster (set-ratelimiter).

@Test
public void testReturnsCollectionTreeWithoutClusterLevelExtras() throws Exception {
Map<String, Object> clusterState = clusterObject(getCluster(""));
assertNull(clusterState.get("live_nodes"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I suppose!

Map<String, Object> clusterState =
clusterObject(
getCluster("?liveNodes=true&aliases=true&clusterProperties=true&includeAll=true"));
assertNull(clusterState.get("live_nodes"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wht happens when random params are provided? do we blow up or do we ignore them? what is the Jersey "right" answer for that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we ignore... undeclared query params don’t bind on the jax-rs method, and we don’t read them from the raw request either. jersey’s usual default is to ignore unknown query params; blowing up would need an explicit policy (bean validation / filter) across v2.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right... the bean validation stuff... I actually really wish that stuff was simpler/nicer in Jersey... More like how Rails handles that stuff...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to double check this page... do we actually want this level of doc on this page? every api will be a v2 api, and we have the tabs pattern.... I think maybe we are reducing this page (in another PR?) content to just maybe what is the v2 api and what a user would need to know.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, fair.. i only updated the existing /api/cluster row and the curl example so it matches the real payload. dropped the extra “what’s excluded” prose from this page.. real contract lives on the cluster-node-management page.

+
v1 only.
If set to true, returns the cluster alias map.
The v2 API does not return this map; use `GET /api/aliases`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

----

*Output*
*V1 output*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a seperate v2 api output?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually no, reverted!


=== V2 cluster status

`GET /api/cluster` is now a typed API.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may get backported to solr 10, and honestly, since we are changing v1, i don't know if this ends up being a major change? since i don't think it's widely used yet?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left it for now. v1 is unchanged.. this is a breaking change for v2 GET /api/cluster consumers (admin UI and solr-operator both read that tree). if we backport to 10 we can move/copy the note. will drop it if we rather keep upgrade notes for more widely used surfaces only?

Comment thread solr/webapp/web/js/angular/services.js Outdated
// GET /api/cluster returns {cluster: {collections: ...}}, the collections, shards, and
// replicas tree. Live nodes, the alias map, and cluster properties are not in this payload.
// This stays a plain $resource, like Threads/ParamSet.
return $resource('/api/cluster', {'wt':'json', '_':Date.now()}, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COuldn't we just use the strongly type JS object here?

@iprithv iprithv Sep 29, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterApi.getClusterStatus is generated now (tag cluster)
ClusterV2 already wraps solrApi.ClusterApi...the call sites still use Collections.status(...) with the $resource callback shape (data.cluster.collections), so switching means rewriting those controllers to the error-first generated client style. can we do that as follow-up?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i supposed... one thing is, if you do it here, we can test things out from a UI perspective, and then move it to a seperate PR....

@iprithv iprithv Oct 2, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated :) admin UI now uses ClusterV2.getClusterStatus. also typed router + replicationFactor on CollectionState so the overview page still gets those

Screenshot 2026-10-02 at 4 12 28 PM

@epugh epugh self-assigned this Sep 27, 2026
@iprithv
iprithv force-pushed the SOLR-18450-cluster-status-v2 branch from 802e921 to 4780ae3 Compare September 29, 2026 22:54
@iprithv
iprithv requested review from epugh and janhoy September 29, 2026 23:10
@github-actions github-actions Bot added dependencies Dependency upgrades tool:build labels Oct 2, 2026
@epugh

epugh commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@iprithv this is a big refactor based on @dsmiley feedback on the JIRA and my most recent email on the thread that all of this belongs under /api/collections, and that we actually need something quite different under /api/cluster...

Thanks for all your hard work on this PR, moving it was pretty easy because of the work you had done!

@github-actions github-actions Bot removed dependencies Dependency upgrades tool:build labels Oct 2, 2026
if (collection != null) {
recordCollectionForLogAndTracing(collection, solrQueryRequest);
}
// Bind only the documented query params; anything else on the request is ignored.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i suppose this comment is okay. This is I bleieve the actual default behavior of all v2 aps...

import org.junit.ClassRule;
import org.junit.Test;

/** Standalone coverage for {@code GET /api/collections?detailed=true}. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose. Do we need to test that a cloud feature fails nicely on standalone?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah...detailed=true is the new cloud-only path, so locking the 400 on standalone seems worth keeping

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay. I look forward to the day we remove standalone and just run "single node Solr Cloud" and call it "Solr Mode" ;-)

@epugh epugh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but will ping @iprithv to review my latest changes.... Would love his +1 as well.

@iprithv

iprithv commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

makes sense putting the tree under collections.. looks good!

+1

@epugh epugh changed the title SOLR-18450: Make GET /api/cluster return only the collections tree SOLR-18450: Relocate GET /api/cluster under /api/collections and return only the collections tree Oct 3, 2026
@epugh

epugh commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Going to merge on Tuesday oct 6th... I've emailed the dev thread to ask for final review.

@epugh

epugh commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

This should also close https://issues.apache.org/jira/browse/SOLR-17422 !

@epugh epugh added this to the 10.x milestone Oct 6, 2026
# Conflicts:
#	solr/solr-ref-guide/modules/configuration-guide/pages/v2-api.adoc
#	solr/solr-ref-guide/modules/deployment-guide/pages/cluster-node-management.adoc
#	solr/webapp/web/js/angular/services.js
@epugh
epugh merged commit 0cfeeb2 into apache:main Oct 6, 2026
7 checks passed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon doing a backport as indicated by the Milestone, I see this PR touches this ref guide page for 11, which rightfully doesn't exist in branch_10x. If the intent is to make this change in 10x then it should be documented on the 10x page not the 11x one. So there's an inconsistency here. IMO either move the docs or this stays in 11x (change Milestone accordingly). @epugh

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. Neither the upgrade note nor the changelog says that GET /api/cluster no longer exists. Even if we declare V2 as experimental, we can call it out in upgrade notes when an entire API is removed.
  2. If we decide to backport to 10.2, the release note must move to ...-in-solr-10.adoc, and we could also consider adding in a (deprecated) shim GET /api/cluster endpoint calling /api/collections. Since SolrOperator uses V1 for clusterstatus, I don't think such a shim is crucial though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

admin-ui cat:api documentation Improvements or additions to documentation tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants