SOLR-15752: Migrate admin UI to v2 apis - #4659
Conversation
We don't yet have the plumbing appaerntly to push the updates to "all" nodes in the V2 api.
|
Created https://issues.apache.org/jira/browse/SOLR-18318 to track blocker to finishing this. |
|
Migrated to V2
Still on v1 — deliberately, with a documented reason
|
|
Merging #4661 unblocks the move to V2 for cloud.js. |
The V2 client callback runs outside Angular's digest cycle, so setting $scope.reloadSuccess/reloadFailure directly (with only the delayed reset wrapped in $timeout) never triggered a re-render -- the ng-class success/warn flash on the Reload button silently never appeared. Wrap the whole callback body in $timeout instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same digest-cycle issue as cores.js's reloadCore: deleteShard, deleteReplica, addReplica, and reloadCollection set their success/failure/deleted flags outside $timeout, so the ng-class indicators never rendered. Wrap each callback body in $timeout. Also found and fixed a separate bug in reloadCollection while verifying the above: CollectionsApi.reloadCollection requires (collectionName, opts, callback), but the call only passed (collectionName, callback) -- the callback function was landing in the opts slot, so the generated client's `if (callback)` guard silently no-op'd and neither branch ever ran. Confirmed via browser testing that reload requests fired but had zero UI effect until this was fixed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
janhoy
left a comment
There was a problem hiding this comment.
Impressive work - for a UI that is going away :)
I spot checked some files, and it is exactly what I expected. However, don't have time to go in detail on each conversion or to spin it up for a thorough test in the UI.
So I take the easy way out and ask our friend Copilot to do a thorough code review, perhaps they find some nasty bug or typo for us...
There was a problem hiding this comment.
Pull request overview
This PR migrates the Solr Admin UI’s AngularJS data-access layer from v1 admin endpoints toward v2 /api endpoints, primarily by introducing v2 OpenAPI client-backed factories and updating controllers to use them.
Changes:
- Added v2 (
*V2) service factories that wrap generatedsolrApiclients and updated multiple controllers to call v2 APIs. - Kept a small set of v1
$resourceservices where v2 equivalents aren’t available/complete yet (e.g., cluster status, threads, paramsets routing nuances, logging setLevel broadcast). - Updated ParamSet consumers to pass an explicit
indexType(coresvscollections) required by the v2 config/params routing.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| solr/webapp/web/js/angular/services.js | Introduces multiple *V2 factories and adjusts remaining v1 $resource services for endpoints that still require them. |
| solr/webapp/web/js/angular/controllers/segments.js | Switches segments page to use SegmentsV2 client calls. |
| solr/webapp/web/js/angular/controllers/security.js | Switches system info loading to SystemV2.getNodeSystemInfo. |
| solr/webapp/web/js/angular/controllers/query.js | Adds indexType when calling ParamSet APIs. |
| solr/webapp/web/js/angular/controllers/paramsets.js | Adds indexType routing support and basic client-side validation before submit. |
| solr/webapp/web/js/angular/controllers/logging.js | Migrates log events/levels listing to LoggingV2 while keeping v1 for broadcast setLevel. |
| solr/webapp/web/js/angular/controllers/index.js | Switches system info dashboard to SystemV2.getNodeSystemInfo. |
| solr/webapp/web/js/angular/controllers/cores.js | Migrates core admin operations to CoresV2 client calls. |
| solr/webapp/web/js/angular/controllers/collections.js | Migrates aliases/shards/replicas/configsets/node listing to v2 clients, retaining cluster status via $resource. |
| solr/webapp/web/js/angular/controllers/cloud.js | Switches node system-info loading to SystemV2.getNodeSystemInfo for cloud nodes view. |
| solr/webapp/web/js/angular/app.js | Updates main navigation/menu refresh logic to use v2 clients for cores/collections/aliases/system. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| segment.deletedDocSize = Math.floor((segment.delCount / segment.size) * segment.totalSize); | ||
| if (segment.delDocSize <= 0.001) delete segment.deletedDocSize; |
| SystemV2.getNodeSystemInfo({"nodes": liveNodesToShow.join(',')}, function (error, data, response) { | ||
| if (error) { | ||
| console.error('Failed to fetch node system info:', error); | ||
| return; | ||
| } | ||
| $timeout(function() { | ||
| var systemResponse = response.body; | ||
| for (var node in systemResponse) { |
| if (!$scope.newCore.name) { | ||
| $scope.addMessage = "Please provide a core name"; | ||
| } else if (false) { //@todo detect whether core exists | ||
| $scope.AddMessage = "A core with that name already exists"; | ||
| } else { |
|
Okay, had claude via playwright give this a good testing, and I did a bunch of manual testing. I think it's ready for final review and merging in a few days... |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 12 changed files in this pull request and generated no new comments.
Suppressed comments (12)
solr/webapp/web/js/angular/controllers/cores.js:129
- On v2 API errors, this handler sets a local message but skips ApiErrorHandler, so 401/403 won’t trigger the expected login redirect/authz banner. Call ApiErrorHandler.handle(response) when error is present.
if (error) {
$scope.renameMessage = "Error renaming core: " + error;
return;
}
solr/webapp/web/js/angular/controllers/cores.js:34
- This loop uses an implicit global variable (firstCore). Declare it with var to avoid leaking globals and accidental cross-scope reuse.
for (firstCore in cores) break;
solr/webapp/web/js/angular/app.js:576
- This loop uses an implicit global variable (key). Declare it with var to avoid leaking globals and accidental cross-scope reuse.
for (key in cdata.collections) {
solr/webapp/web/js/angular/controllers/cores.js:159
- On v2 API errors, this handler sets a local message but skips ApiErrorHandler, so 401/403 won’t trigger the expected login redirect/authz banner. Call ApiErrorHandler.handle(response) when error is present.
if (error) {
$scope.swapMessage = "Error swapping cores: " + error;
return;
}
solr/webapp/web/js/angular/controllers/cores.js:89
- On v2 API errors, this handler sets a local message but skips ApiErrorHandler, so 401/403 won’t trigger the expected login redirect/authz banner. Call ApiErrorHandler.handle(response) when error is present.
This issue also appears in the following locations of the same file:
- line 126
- line 156
if (error) {
$scope.addMessage = "Error creating core: " + error;
return;
}
solr/webapp/web/js/angular/controllers/cores.js:179
- Other CoresV2 methods are called with (core, opts, callback). reloadCore is missing the options argument, so the callback may be treated as opts and never run. Pass an explicit empty options object.
CoresV2.reloadCore($scope.selectedCore,
function(error, data, response) {
solr/webapp/web/js/angular/app.js:545
- $scope.isSecurityEnabled is derived from $scope.authenticationPlugin, but that variable is never set in this controller; this will keep isSecurityEnabled false even when security is enabled. Derive it from the SystemV2 response instead.
$scope.isSecurityEnabled = $scope.authenticationPlugin != null;
solr/webapp/web/js/angular/app.js:525
- This loop uses an implicit global variable (key). Declare it with var to avoid leaking globals and accidental cross-scope reuse.
This issue also appears on line 576 of the same file.
for (key in data.status) {
solr/webapp/web/js/angular/controllers/cores.js:71
- This sets $scope.AddMessage, but the template shows addMessage; the user won’t see this validation error. Use a consistent casing.
$scope.AddMessage = "A core with that name already exists";
solr/webapp/web/js/angular/controllers/cores.js:28
- This loop uses an implicit global variable (_obj). Declare it with var to avoid leaking globals and accidental cross-scope reuse.
This issue also appears on line 34 of the same file.
for (_obj in cores) coreCount++;
solr/webapp/web/js/angular/controllers/logging.js:135
- This loop uses an implicit global variable (level). Declare it with var to avoid leaking globals and accidental cross-scope reuse.
for (level in data.levels) {
solr/webapp/web/js/angular/controllers/segments.js:53
- The check uses segment.delDocSize (undefined) instead of segment.deletedDocSize, so the delete branch never triggers. Also, deleting deletedDocSize before computing aliveDocSize can yield NaN. Use the correct property and compute aliveDocSize before deleting the display-only field.
segment.deletedDocSize = Math.floor((segment.delCount / segment.size) * segment.totalSize);
if (segment.delDocSize <= 0.001) delete segment.deletedDocSize;
segment.aliveDocSize = segment.totalSize - segment.deletedDocSize;

https://issues.apache.org/jira/browse/SOLR-15752
Description
Start using V2 apis in our solr admin. We need to use them "in anger" if we want to build confidence in them, and to help us move away from v1 equivalents.
Solution
Work with Claude to do the updates to our javascript from v1 to v2. We don't have tests, so this is all manually tested.
We use the real generated
solrApiclient classesCoresApi,CollectionsApi,AliasesApi,ShardsApi,ReplicasApi,ConfigsetsApi,ClusterApi,SystemApi,LoggingApi,SegmentsApivia the*V2factories inservices.js.We bumped to using the older style v2 without the strongly typed client for
Collections (specically CLUSTERSTATUS),Threads,ParamSet.Tests
Sigh. No JS tests. And not ready to even begin that!