Repository navigation
SOLR-18450: Relocate GET /api/cluster under /api/collections and return only the collections tree - #4952
Conversation
| * 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 |
There was a problem hiding this comment.
i guess this comment about what it doesn't do is fine as we wait to get rid of v1...
2e8e327 to
d076904
Compare
|
|
||
| @Schema( | ||
| description = | ||
| "Cluster geometry. Does not include live nodes, the alias map, or cluster properties.") |
There was a problem hiding this comment.
i think we don't need the the Does Not aspects in the descritiption. We highlight that int he docs..
There was a problem hiding this comment.
agreed, trimmed wording here.
| recordCollectionForLogAndTracing(collection, solrQueryRequest); | ||
| } | ||
|
|
||
| // Only the parameters this API documents. includeAll, liveNodes, aliases, and |
There was a problem hiding this comment.
yeah, not sure we should still be documenting the includeAll and liveNodes etc at this level. One comment, okay, but seems like too many
There was a problem hiding this comment.
what happens if you pass them in? does it get run?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"))) { |
There was a problem hiding this comment.
huh.... is this part of a rolling upgrade feature?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
is there also a registerV2 Api method on this guy which can be removed?
There was a problem hiding this comment.
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")); |
| Map<String, Object> clusterState = | ||
| clusterObject( | ||
| getCluster("?liveNodes=true&aliases=true&clusterProperties=true&includeAll=true")); | ||
| assertNull(clusterState.get("live_nodes")); |
There was a problem hiding this comment.
wht happens when random params are provided? do we blow up or do we ignore them? what is the Jersey "right" answer for that?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
oh right... the bean validation stuff... I actually really wish that stuff was simpler/nicer in Jersey... More like how Rails handles that stuff...
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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`. |
| ---- | ||
|
|
||
| *Output* | ||
| *V1 output* |
There was a problem hiding this comment.
do we need a seperate v2 api output?
There was a problem hiding this comment.
actually no, reverted!
|
|
||
| === V2 cluster status | ||
|
|
||
| `GET /api/cluster` is now a typed API. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
| // 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()}, { |
There was a problem hiding this comment.
COuldn't we just use the strongly type JS object here?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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....
802e921 to
4780ae3
Compare
…n V2 Keep original V1 where it is.
|
@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! |
| if (collection != null) { | ||
| recordCollectionForLogAndTracing(collection, solrQueryRequest); | ||
| } | ||
| // Bind only the documented query params; anything else on the request is ignored. |
There was a problem hiding this comment.
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}. */ |
There was a problem hiding this comment.
I suppose. Do we need to test that a cloud feature fails nicely on standalone?
There was a problem hiding this comment.
yeah...detailed=true is the new cloud-only path, so locking the 400 on standalone seems worth keeping
There was a problem hiding this comment.
okay. I look forward to the day we remove standalone and just run "single node Solr Cloud" and call it "Solr Mode" ;-)
|
makes sense putting the tree under collections.. looks good! +1 |
|
Going to merge on Tuesday oct 6th... I've emailed the dev thread to ask for final review. |
|
This should also close https://issues.apache.org/jira/browse/SOLR-17422 ! |
# 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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Two things:
- Neither the upgrade note nor the changelog says that
GET /api/clusterno longer exists. Even if we declare V2 as experimental, we can call it out in upgrade notes when an entire API is removed. - 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) shimGET /api/clusterendpoint calling/api/collections. Since SolrOperator uses V1 for clusterstatus, I don't think such a shim is crucial though

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.