Migrate org.apache.solr.cli tools from V1 to V2 APIs#4154
Migrate org.apache.solr.cli tools from V1 to V2 APIs#4154epugh wants to merge 9 commits intoapache:mainfrom
Conversation
Co-authored-by: epugh <22395+epugh@users.noreply.github.com>
…r/nodes + /collections APIs Co-authored-by: epugh <22395+epugh@users.noreply.github.com>
… POJOs Co-authored-by: epugh <22395+epugh@users.noreply.github.com>
Co-authored-by: epugh <22395+epugh@users.noreply.github.com>
dsmiley
left a comment
There was a problem hiding this comment.
looks good; just some minor feedback
|
Right now, Solr allows users to disable the v2 APIs with a boolean sysprop: I'm 100% in favor of using the v2 APIs in more places - we desperately need that dog-fooding on them and this is a great way to do that. But if we're going to do this then we need to rip out that sysprop. Ideally that'd happen before this PR gets merged, just to make sure we don't forget about it and accidentally release something where the |
Good find! Yeah, I had forgotten about that setting. We could just commit these to For various v2 api's that we want to have flexiblity on, can we keep them as "experimental" for a little longer, so we don't have to worry about back compat, with the idea that internal to solr consumers, like the CLI (or maybe internal APIS) wouldn't care that we are changing them over time... |
FYI that these links are "private" AFAIK - I get a 404 when trying to click through.
I started out writing a reply to this that said essentially: "Sure, why not. Solr offers plenty of feature flags, and there's no clear correlation between those and 'experimental'-ness. Lots of non-experimental features have flags. And there are plenty of other 'experimental' features that don't have a feature flag. No reason to tie these things together." But in writing that and reading it over I find I've unconvinced myself 😦 The problem here is security. I don't know of any security issues specific to the v2 API, but it's a whole new attack surface. While we're signaling that it's not ready for prime time then I think a subset of users are going to want to be able to disable it. Telling them: "here's this thing that's not quite ready yet, pray it doesn't expose you in some way" is not a great message. This feels like a much larger discussion and I don't want it to hold up this PR. Would you be OK making this "main"-only for now, and I'll file a JIRA ticket or dev@ thread to figure out a path forward here? The dust may settle on that discussion in a few weeks and we decide we're OK with this hitting |
I love a suggestion that keeps me unblocked ;-). I think Interesting, I think of these as experimental not because of security but because we aren't sure we have the right flavour of API. Somethign I've noticed lately is that when I build APIs, that then, later, when I use them "for real" I find a lot of issues with them not being "quite right" yet. Not because of security or performacnce, but maybe because of too much paylard returned or not enough filters or what not. So yeah, please do move forward, and I'll merge this to |
gerlowskija
left a comment
There was a problem hiding this comment.
Found one bug in your code I think; see comments inline.
Also, this PR adds a whole new API (ListClusterNodes), so it probably deserves a changelog entry and some tests that use the generated v2 request.
| @SuppressWarnings("unchecked") | ||
| List<String> collections = (List<String>) existsCheckResult.get("collections"); | ||
| exists = collections != null && collections.contains(collection); | ||
| var response = new CollectionsApi.ListCollections().process(solrClient); |
There was a problem hiding this comment.
[0] I may be out of date, but as of one point at least these generated v2 request/response objects didn't throw exception on errors the way everything else in SolrJ does.
Assuming this is still true, users are responsible for inspecting the .responseHeader.status field to make sure that the operation succeeded. Hopefully I'm wrong, but if not you'll need to add that checking here and elsewhere.
|
|
||
| // TODO get this as a metric from the metrics API instead, or something else. | ||
| var collections = (Map<String, Object>) json._get(List.of("cluster", "collections"), null); | ||
| var collectionsResponse = new CollectionsApi.ListCollections().process(solrClient); |
There was a problem hiding this comment.
[-1] The original code here was grabbing the .cluster.collections bit of the CLUSTERSTATUS response, which includes tons of info:
"cluster":{
"live_nodes":["localhost:8983_solr"],
"collections":{
"foo":{
"pullReplicas":"0",
"configName":"foo",
"nrtReplicas":1,
"replicationFactor":1,
"tlogReplicas":"0",
"router":{
"name":"compositeId"
},
....
Are you dropping all that info on purpose in your replacement, or was that a mistake?
| /** | ||
| * V2 API for listing the live nodes in the SolrCloud cluster. | ||
| * | ||
| * <p>This API (GET /v2/cluster/nodes) is equivalent to the v1 CLUSTERSTATUS action filtered to |
There was a problem hiding this comment.
[0] IMO the API comparison is a bit clearer if you put the verbatim v1 request here that you're comparing the v2 API to, rather than trying to describe it.
i.e. /admin/collections?action=CLUSTERSTATUS&liveNodes=true&includeAll=false
… back to old style V2 api creation

Replaces legacy V1 admin API calls (
CollectionAdminRequest,CoreAdminRequest) in thebin/solrCLI tools with generated V2 OpenAPI SolrJ classes. Also adds a new proper SolrJ V2 endpoint forGET /cluster/nodesthat was previously missing, eliminating the need for aGenericV2SolrRequestworkaround.I used Copilot for this, and here is the agent chat: https://github.com/epugh/solr/tasks/3c2f15c6-c0c7-4e39-b6b6-1cd51f8e7aa4
Migrated calls
CLIUtilssafeCheckCollectionExistsCollectionAdminRequest.List→CollectionsApi.ListCollectionsCreateToolcreateCoreCoreAdminRequest.createCore→CoresApi.CreateCoreCreateToolcreateCollectionCollectionAdminRequest.createCollection→CollectionsApi.CreateCollectionDeleteTooldeleteCollectionCollectionAdminRequest.deleteCollection→CollectionsApi.DeleteCollectionDeleteTooldeleteCoreCoreAdminRequest.Unload→CoresApi.UnloadCoreStatusToolgetCloudStatusCollectionAdminRequest.ClusterStatus→ClusterApi.ListClusterNodes+CollectionsApi.ListCollectionsVerbose output restored via Jackson
The old V1 code serialized
NamedListresponses with noggit'sJSONWriter. V2 response POJOs are Jackson-annotated, so verbose output now usesJacksonContentWriter.DEFAULT_MAPPER.writerWithDefaultPrettyPrinter()— actually cleaner output since the responses are already proper JSON objects:New
GET /cluster/nodesV2 API (SolrJ support)StatusToolpreviously fell back toGenericV2SolrRequestbecause SolrJ had no typed class for this endpoint. The full API pipeline was wired up:ListClusterNodesResponse— new model withSet<String> nodesListClusterNodesApi— new endpoint interface at@Path("/cluster/nodes")ListClusterNodes— new Jersey implementation registered inCollectionsHandlerClusterApi.ListClusterNodes— generated SolrJ request class (replacesGenericV2SolrRequest)Not migrated
Snapshot tools (
SnapshotCreateTool,SnapshotDeleteTool, etc.) are intentionally excluded as candidates for removal.In fact, we may just remove them...?
Tests
Existing tests + bats tests all pass.