This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 6df6cb73272 SOLR-15752: Migrate admin UI to v2 apis (#4659)
6df6cb73272 is described below
commit 6df6cb732725b247e4e039778164f55163c4e91c
Author: Eric Pugh <[email protected]>
AuthorDate: Wed Aug 26 14:42:23 2026 -0400
SOLR-15752: Migrate admin UI to v2 apis (#4659)
Co-authored-by: Claude Sonnet 5 <[email protected]>
---
solr/webapp/web/js/angular/app.js | 173 ++++++++++--------
solr/webapp/web/js/angular/controllers/cloud.js | 88 +++++----
.../web/js/angular/controllers/collections.js | 203 ++++++++++++---------
solr/webapp/web/js/angular/controllers/cores.js | 144 +++++++++------
solr/webapp/web/js/angular/controllers/index.js | 195 ++++++++++----------
solr/webapp/web/js/angular/controllers/logging.js | 104 ++++++-----
solr/webapp/web/js/angular/controllers/login.js | 2 +
.../webapp/web/js/angular/controllers/paramsets.js | 36 +++-
solr/webapp/web/js/angular/controllers/query.js | 12 +-
solr/webapp/web/js/angular/controllers/security.js | 40 ++--
solr/webapp/web/js/angular/controllers/segments.js | 52 +++---
solr/webapp/web/js/angular/services.js | 182 ++++++++++++------
12 files changed, 729 insertions(+), 502 deletions(-)
diff --git a/solr/webapp/web/js/angular/app.js
b/solr/webapp/web/js/angular/app.js
index 1ff0cb824f2..27a2f458682 100644
--- a/solr/webapp/web/js/angular/app.js
+++ b/solr/webapp/web/js/angular/app.js
@@ -478,6 +478,19 @@ solrAdminApp.config([
$httpProvider.interceptors.push("httpInterceptor");
// Force BasicAuth plugin to serve us a 'Authorization: xBasic xxxx' header
so browser will not pop up login dialogue
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
+ // The V2 solrApi client (superagent-based) never goes through
$httpProvider, so X-Requested-With
+ // (for the same popup-suppression trick) needs its own copy here.
+ solrApi.ApiClient.instance.defaultHeaders['X-Requested-With'] =
'XMLHttpRequest';
+ // Authorization is set via a superagent plugin instead of defaultHeaders,
so it's re-read from
+ // sessionStorage on every request -- same as $http gets via
httpInterceptor.started above -- and
+ // there's a single place to keep in sync (nowhere else should touch
+ // solrApi.ApiClient.instance.defaultHeaders['Authorization']).
+ solrApi.ApiClient.instance.plugins = [function(request) {
+ if (sessionStorage.getItem("auth.header")) {
+ request.set('Authorization', sessionStorage.getItem("auth.header"));
+ }
+ return request;
+ }];
// Suppress AngularJS 1.6+ "Possibly unhandled rejection" console noise;
errors are handled via callbacks and the security/schema-designer error dialogs
$qProvider.errorOnUnhandledRejections(false);
})
@@ -497,7 +510,7 @@ solrAdminApp.config([
};
});
-solrAdminApp.controller('MainController', function($scope, $route, $rootScope,
$location, Cores, Collections, System, Ping, Constants, SchemaDesigner) {
+solrAdminApp.controller('MainController', function($scope, $route, $rootScope,
$location, $timeout, CoresV2, CollectionsV2, AliasesV2, SystemV2, Ping,
Constants, SchemaDesigner, ApiErrorHandler) {
$rootScope.exceptions={};
@@ -518,86 +531,98 @@ solrAdminApp.controller('MainController',
function($scope, $route, $rootScope, $
$scope.refresh();
$scope.resetMenu = function(page, pageType) {
- Cores.list(function(data) {
- $scope.cores = [];
- var currentCoreName = $route.current.params.core;
- delete $scope.currentCore;
- for (key in data.status) {
- var core = data.status[key];
- if (core.name.startsWith("._designer_")) {
- continue;
- }
- $scope.cores.push(core);
- if ((!$scope.isSolrCloud || pageType == Constants.IS_CORE_PAGE) &&
core.name == currentCoreName) {
- $scope.currentCore = core;
+ CoresV2.getAllCoreStatus({indexInfo: false}, function(error, data,
response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.cores = [];
+ var currentCoreName = $route.current.params.core;
+ delete $scope.currentCore;
+ for (var key in data.status) {
+ var core = data.status[key];
+ if (core.name.startsWith("._designer_")) {
+ continue;
+ }
+ $scope.cores.push(core);
+ if ((!$scope.isSolrCloud || pageType == Constants.IS_CORE_PAGE) &&
core.name == currentCoreName) {
+ $scope.currentCore = core;
+ }
}
- }
- $scope.showInitFailures = Object.keys(data.initFailures).length>0;
- $scope.initFailures = data.initFailures;
+ $scope.showInitFailures = Object.keys(data.initFailures).length>0;
+ $scope.initFailures = data.initFailures;
+ });
});
- System.get(function(data) {
- $scope.isCloudEnabled = data.mode.match( /solrcloud/i );
- $scope.usersPermissions = data.security.permissions;
- $scope.isSecurityEnabled = $scope.authenticationPlugin != null;
-
- $scope.isSchemaDesignerEnabled = $scope.isPermitted([
- permissions.CONFIG_EDIT_PERM,
- permissions.SCHEMA_EDIT_PERM,
- permissions.READ_PERM,
- permissions.UPDATE_PERM
- ]);
-
- var currentCollectionName = $route.current.params.core;
- delete $scope.currentCollection;
- if ($scope.isCloudEnabled) {
- Collections.list(function (cdata) {
- Collections.listaliases(function (adata) {
- $scope.aliases = [];
- for (var key in adata.aliases) {
- props = {};
- if (key in adata.properties) {
- props = adata.properties[key];
- }
- var alias = {name: key, collections: adata.aliases[key], type:
'alias', properties: props};
- $scope.aliases.push(alias);
- if (pageType == Constants.IS_COLLECTION_PAGE && alias.name ==
currentCollectionName) {
- $scope.currentCollection = alias;
- }
- }
- $scope.collections = [];
- for (key in cdata.collections) {
- if (cdata.collections[key].startsWith("._designer_")) {
- continue; // ignore temp designer collections
- }
- var collection = {name: cdata.collections[key], type:
'collection'};
- $scope.collections.push(collection);
- if (pageType == Constants.IS_COLLECTION_PAGE && collection.name
== currentCollectionName) {
- $scope.currentCollection = collection;
- }
- }
+ SystemV2.getNodeSystemInfo({}, function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.isCloudEnabled = data.mode.match( /solrcloud/i );
+ $scope.usersPermissions = data.security.permissions;
+ $scope.isSecurityEnabled = data.security.authenticationPlugin != null;
+
+ $scope.isSchemaDesignerEnabled = $scope.isPermitted([
+ permissions.CONFIG_EDIT_PERM,
+ permissions.SCHEMA_EDIT_PERM,
+ permissions.READ_PERM,
+ permissions.UPDATE_PERM
+ ]);
+
+ var currentCollectionName = $route.current.params.core;
+ delete $scope.currentCollection;
+ if ($scope.isCloudEnabled) {
+ CollectionsV2.listCollections(function (error, cdata, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ AliasesV2.getAliases(function (error, adata, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.aliases = [];
+ for (var key in adata.aliases) {
+ var props = {};
+ if (key in adata.properties) {
+ props = adata.properties[key];
+ }
+ var alias = {name: key, collections: adata.aliases[key],
type: 'alias', properties: props};
+ $scope.aliases.push(alias);
+ if (pageType == Constants.IS_COLLECTION_PAGE && alias.name
== currentCollectionName) {
+ $scope.currentCollection = alias;
+ }
+ }
+ $scope.collections = [];
+ for (var key in cdata.collections) {
+ if (cdata.collections[key].startsWith("._designer_")) {
+ continue; // ignore temp designer collections
+ }
+ var collection = {name: cdata.collections[key], type:
'collection'};
+ $scope.collections.push(collection);
+ if (pageType == Constants.IS_COLLECTION_PAGE &&
collection.name == currentCollectionName) {
+ $scope.currentCollection = collection;
+ }
+ }
- $scope.aliases_and_collections = $scope.aliases;
- if ($scope.aliases.length > 0) {
- $scope.aliases_and_collections =
$scope.aliases_and_collections.concat({name:'-----'});
- }
- $scope.aliases_and_collections =
$scope.aliases_and_collections.concat($scope.collections);
+ $scope.aliases_and_collections = $scope.aliases;
+ if ($scope.aliases.length > 0) {
+ $scope.aliases_and_collections =
$scope.aliases_and_collections.concat({name:'-----'});
+ }
+ $scope.aliases_and_collections =
$scope.aliases_and_collections.concat($scope.collections);
+ });
+ });
+ });
});
- });
- }
-
- $scope.showEnvironment = data.environment !== undefined;
- if (data.environment) {
- $scope.environment = data.environment;
- var env_labels = {'prod': 'Production', 'stage': 'Staging', 'test':
'Test', 'dev': 'Development'};
- $scope.environment_label = env_labels[data.environment];
- if (data.environment_label) {
- $scope.environment_label = data.environment_label;
}
- if (data.environment_color) {
- $scope.environment_color = data.environment_color;
+
+ $scope.showEnvironment = data.environment !== undefined;
+ if (data.environment) {
+ $scope.environment = data.environment;
+ var env_labels = {'prod': 'Production', 'stage': 'Staging', 'test':
'Test', 'dev': 'Development'};
+ $scope.environment_label = env_labels[data.environment];
+ if (data.environment_label) {
+ $scope.environment_label = data.environment_label;
+ }
+ if (data.environment_color) {
+ $scope.environment_color = data.environment_color;
+ }
}
- }
+ });
});
$scope.showingLogging = page.lastIndexOf("logging", 0) === 0;
diff --git a/solr/webapp/web/js/angular/controllers/cloud.js
b/solr/webapp/web/js/angular/controllers/cloud.js
index f045583ef7f..e5b2b1483e8 100644
--- a/solr/webapp/web/js/angular/controllers/cloud.js
+++ b/solr/webapp/web/js/angular/controllers/cloud.js
@@ -16,7 +16,7 @@
*/
solrAdminApp.controller('CloudController',
- function($scope, $location, Zookeeper, Constants, Collections, System,
Metrics, MetricsExtractor, ZookeeperStatus) {
+ function($scope, $location, $timeout, Zookeeper, Constants, Collections,
SystemV2, Metrics, MetricsExtractor, ZookeeperStatus, ApiErrorHandler) {
$scope.showDebug = false;
@@ -37,7 +37,7 @@ solrAdminApp.controller('CloudController',
graphSubController($scope, Zookeeper, false);
} else if (view === "nodes") {
$scope.resetMenu("cloud-nodes", Constants.IS_ROOT_PAGE);
- nodesSubController($scope, Collections, System, Metrics,
MetricsExtractor);
+ nodesSubController($scope, $timeout, Collections, SystemV2,
Metrics, MetricsExtractor, ApiErrorHandler);
} else if (view === "zkstatus") {
$scope.resetMenu("cloud-zkstatus", Constants.IS_ROOT_PAGE);
zkStatusSubController($scope, ZookeeperStatus, false);
@@ -107,7 +107,7 @@ function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
-var nodesSubController = function($scope, Collections, System, Metrics,
MetricsExtractor) {
+var nodesSubController = function($scope, $timeout, Collections, SystemV2,
Metrics, MetricsExtractor, ApiErrorHandler) {
$scope.pageSize = 10;
$scope.showNodes = true;
$scope.showTree = false;
@@ -353,43 +353,51 @@ var nodesSubController = function($scope, Collections,
System, Metrics, MetricsE
Fetch system info for all selected nodes
Pick the data we want to display and add it to the node-centric data
structure
*/
- System.get({"nodes": liveNodesToShow.join(',')}, function (systemResponse)
{
- for (var node in systemResponse) {
- if (node in nodes) {
- var s = systemResponse[node];
- nodes[node]['system'] = s;
- var memTotal = s.system.totalPhysicalMemorySize;
- var memFree = s.system.freePhysicalMemorySize;
- var memPercentage = Math.floor((memTotal - memFree) / memTotal *
100);
- nodes[node]['memUsedPct'] = memPercentage;
- nodes[node]['memUsedPctStyle'] = styleForPct(memPercentage);
- nodes[node]['memTotal'] = bytesToSize(memTotal);
- nodes[node]['memFree'] = bytesToSize(memFree);
- nodes[node]['memUsed'] = bytesToSize(memTotal - memFree);
-
- var heapMax = s.jvm.memory.raw.max;
- var heapTotal = s.jvm.memory.raw.total;
- var heapFree = s.jvm.memory.raw.free;
- var heapPercentage = Math.floor((heapTotal - heapFree) / heapMax *
100);
- nodes[node]['heapUsed'] = bytesToSize(heapTotal - heapFree);
- nodes[node]['heapUsedPct'] = heapPercentage;
- nodes[node]['heapUsedPctStyle'] = styleForPct(heapPercentage);
- nodes[node]['heapMax'] = bytesToSize(heapMax);
- nodes[node]['heapTotal'] = bytesToSize(heapTotal);
- nodes[node]['heapFree'] = bytesToSize(heapFree);
-
- var jvmUptime = s.jvm.jmx.upTimeMS / 1000; // Seconds
- nodes[node]['jvmUptime'] = secondsForHumans(jvmUptime);
- nodes[node]['jvmUptimeSec'] = jvmUptime;
-
- nodes[node]['uptime'] = (s.system.uptime || "unknown").replace(/.*up
(.*?,.*?),.*/, "$1");
- nodes[node]['loadAvg'] = Math.round(s.system.systemLoadAverage *
100) / 100;
- nodes[node]['cpuPct'] = Math.ceil(s.system.processCpuLoad * 100);
- nodes[node]['cpuPctStyle'] =
styleForPct(Math.ceil(s.system.processCpuLoad));
- nodes[node]['maxFileDescriptorCount'] =
s.system.maxFileDescriptorCount;
- nodes[node]['openFileDescriptorCount'] =
s.system.openFileDescriptorCount;
- }
+ SystemV2.getNodeSystemInfo({"nodes": liveNodesToShow.join(',')}, function
(error, data, response) {
+ if (error) {
+ console.error('Failed to fetch node system info:', error);
+ ApiErrorHandler.handle(response);
+ return;
}
+ $timeout(function() {
+ var systemResponse = response.body;
+ for (var node in systemResponse) {
+ if (node in nodes) {
+ var s = systemResponse[node];
+ nodes[node]['system'] = s;
+ var memTotal = s.system.totalPhysicalMemorySize;
+ var memFree = s.system.freePhysicalMemorySize;
+ var memPercentage = Math.floor((memTotal - memFree) / memTotal *
100);
+ nodes[node]['memUsedPct'] = memPercentage;
+ nodes[node]['memUsedPctStyle'] = styleForPct(memPercentage);
+ nodes[node]['memTotal'] = bytesToSize(memTotal);
+ nodes[node]['memFree'] = bytesToSize(memFree);
+ nodes[node]['memUsed'] = bytesToSize(memTotal - memFree);
+
+ var heapMax = s.jvm.memory.raw.max;
+ var heapTotal = s.jvm.memory.raw.total;
+ var heapFree = s.jvm.memory.raw.free;
+ var heapPercentage = Math.floor((heapTotal - heapFree) / heapMax *
100);
+ nodes[node]['heapUsed'] = bytesToSize(heapTotal - heapFree);
+ nodes[node]['heapUsedPct'] = heapPercentage;
+ nodes[node]['heapUsedPctStyle'] = styleForPct(heapPercentage);
+ nodes[node]['heapMax'] = bytesToSize(heapMax);
+ nodes[node]['heapTotal'] = bytesToSize(heapTotal);
+ nodes[node]['heapFree'] = bytesToSize(heapFree);
+
+ var jvmUptime = s.jvm.jmx.upTimeMS / 1000; // Seconds
+ nodes[node]['jvmUptime'] = secondsForHumans(jvmUptime);
+ nodes[node]['jvmUptimeSec'] = jvmUptime;
+
+ nodes[node]['uptime'] = (s.system.uptime ||
"unknown").replace(/.*up (.*?,.*?),.*/, "$1");
+ nodes[node]['loadAvg'] = Math.round(s.system.systemLoadAverage *
100) / 100;
+ nodes[node]['cpuPct'] = Math.ceil(s.system.processCpuLoad * 100);
+ nodes[node]['cpuPctStyle'] =
styleForPct(Math.ceil(s.system.processCpuLoad));
+ nodes[node]['maxFileDescriptorCount'] =
s.system.maxFileDescriptorCount;
+ nodes[node]['openFileDescriptorCount'] =
s.system.openFileDescriptorCount;
+ }
+ }
+ });
});
/*
@@ -792,7 +800,7 @@ var graphSubController = function ($scope, Zookeeper) {
params.filter = filter;
}
- Zookeeper.clusterState(params, function (data) {
+ Zookeeper.clusterState(params, function (data) {
var state = data.znode.data;
var leaf_count = 0;
var graph_data = {
diff --git a/solr/webapp/web/js/angular/controllers/collections.js
b/solr/webapp/web/js/angular/controllers/collections.js
index 830290a1806..93fd5fb1b6d 100644
--- a/solr/webapp/web/js/angular/controllers/collections.js
+++ b/solr/webapp/web/js/angular/controllers/collections.js
@@ -16,19 +16,18 @@
*/
solrAdminApp.controller('CollectionsController',
- function($scope, $routeParams, $location, $timeout, Collections,
CollectionsV2, Zookeeper, Constants, ConfigSets){
+ function($scope, $routeParams, $location, $timeout, Collections,
CollectionsV2, AliasesV2, ShardsV2, ReplicasV2, ConfigSetsV2, ClusterV2,
Constants, ApiErrorHandler){
$scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
$scope.refresh = function() {
$scope.rootUrl = Constants.ROOT_URL + "#/~collections/" +
$routeParams.collection;
- Zookeeper.liveNodes({}, function(data) {
- $scope.availableNodeSet = [];
- var children = data.tree[0].children;
- for (var child in children) {
- $scope.availableNodeSet.push(children[child].text);
- }
+ ClusterV2.listClusterNodes(function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.availableNodeSet = data.nodes;
+ });
});
Collections.status(function (data) {
@@ -62,36 +61,42 @@ solrAdminApp.controller('CollectionsController',
$scope.collection = collection;
}
}
- // Fetch aliases using LISTALIASES to get properties
- Collections.listaliases(function (adata) {
- // TODO: Population of aliases array duplicated in app.js
- $scope.aliases = [];
- for (var key in adata.aliases) {
- props = {};
- if (key in adata.properties) {
- props = adata.properties[key];
+ // Fetch aliases using getAliases to get properties
+ AliasesV2.getAliases(function (error, adata, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ // TODO: Population of aliases array duplicated in app.js
+ $scope.aliases = [];
+ for (var key in adata.aliases) {
+ var props = {};
+ if (key in adata.properties) {
+ props = adata.properties[key];
+ }
+ var alias = {name: key, collections:
adata.aliases[key], type: 'alias', properties: props};
+ $scope.aliases.push(alias);
+ if ($routeParams.collection == 'alias_' + key) {
+ $scope.collection = alias;
+ }
}
- var alias = {name: key, collections: adata.aliases[key],
type: 'alias', properties: props};
- $scope.aliases.push(alias);
- if ($routeParams.collection == 'alias_' + key) {
- $scope.collection = alias;
+ // Decide what is selected in list
+ if ($routeParams.collection && !$scope.collection) {
+ alert("No collection or alias called " +
$routeParams.collection);
+ $location.path("/~collections");
}
- }
- // Decide what is selected in list
- if ($routeParams.collection && !$scope.collection) {
- alert("No collection or alias called " +
$routeParams.collection);
- $location.path("/~collections");
- }
+ });
});
$scope.liveNodes = data.cluster.liveNodes;
});
- ConfigSets.configs(function(data) {
- $scope.configs = [];
- var items = data.configSets;
- for (var i in items) {
- $scope.configs.push({name: items[i]});
- }
+ ConfigSetsV2.listConfigSet(function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.configs = [];
+ var items = data.configSets;
+ for (var i in items) {
+ $scope.configs.push({name: items[i]});
+ }
+ });
});
};
@@ -138,17 +143,23 @@ solrAdminApp.controller('CollectionsController',
for (var i in $scope.aliasCollections) {
collections.push($scope.aliasCollections[i].name);
}
- Collections.createAlias({name: $scope.aliasToCreate, collections:
collections.join(",")}, function(data) {
- $scope.cancelCreateAlias();
- $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
- $location.path("/~collections/alias_" + $scope.aliasToCreate);
+ AliasesV2.createAlias({createAliasRequestBody: {name:
$scope.aliasToCreate, collections: collections}}, function(error, data,
response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.cancelCreateAlias();
+ $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
+ $location.path("/~collections/alias_" + $scope.aliasToCreate);
+ });
});
}
$scope.deleteAlias = function() {
- Collections.deleteAlias({name: $scope.collection.name}, function(data)
{
- $scope.hideAll();
- $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
- $location.path("/~collections/");
+ AliasesV2.deleteAlias($scope.collection.name, {}, function(error,
data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.hideAll();
+ $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
+ $location.path("/~collections/");
+ });
});
};
@@ -162,26 +173,29 @@ solrAdminApp.controller('CollectionsController',
$scope.addMessage = "A collection can't be made up of just PULL
replicas";
} else {
var coll = $scope.newCollection;
- var params = {
+ var createCollectionParams = {
name: coll.name,
- "router.name": coll.routerName,
+ router: {name: coll.routerName},
numShards: coll.numShards,
- "collection.configName": coll.configName
+ config: coll.configName
};
- if (coll.shards) params.shards = coll.shards;
- if (coll.routerField) params["router.field"] = coll.routerField;
- if (coll.createNodeSet) params.createNodeSet =
coll.createNodeSet.join(",");
+ if (coll.shards) createCollectionParams.shardNames =
coll.shards.split(",").map(function(s) { return s.trim(); });
+ if (coll.routerField) createCollectionParams.router.field =
coll.routerField;
+ if (coll.createNodeSet) createCollectionParams.nodeSet =
coll.createNodeSet;
if ($scope.replicaTypesChosen()) {
- params["nrtReplicas"] = coll.nrtReplicas;
- params["tlogReplicas"] = coll.tlogReplicas;
- params["pullReplicas"] = coll.pullReplicas;
+ createCollectionParams.nrtReplicas = coll.nrtReplicas;
+ createCollectionParams.tlogReplicas = coll.tlogReplicas;
+ createCollectionParams.pullReplicas = coll.pullReplicas;
} else {
- params["replicationFactor"] = coll.replicationFactor;
+ createCollectionParams.replicationFactor =
coll.replicationFactor;
}
- Collections.add(params, function(data) {
- $scope.cancelAddCollection();
- $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
- $location.path("/~collections/" + $scope.newCollection.name);
+ CollectionsV2.createCollection({createCollectionRequestBody:
createCollectionParams}, function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.cancelAddCollection();
+ $scope.resetMenu("collections", Constants.IS_ROOT_PAGE);
+ $location.path("/~collections/" + $scope.newCollection.name);
+ });
});
}
};
@@ -202,8 +216,11 @@ solrAdminApp.controller('CollectionsController',
$scope.deleteCollection = function() {
if ($scope.collection.name == $scope.collectionDeleteConfirm) {
- Collections.delete({name: $scope.collection.name}, function (data)
{
- $location.path("/~collections");
+ CollectionsV2.deleteCollection($scope.collection.name, {},
function (error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $location.path("/~collections");
+ });
});
} else {
$scope.deleteMessage = "Collection names do not match.";
@@ -215,15 +232,17 @@ solrAdminApp.controller('CollectionsController',
alert("No collection selected.");
return;
}
- CollectionsV2.reloadCollection($scope.collection.name, function(error,
data,response) {
- if (error) {
- $scope.reloadFailure = true;
- $timeout(function() {$scope.reloadFailure=false}, 1000);
- $location.path("/~collections");
- } else {
- $scope.reloadSuccess = true;
- $timeout(function() {$scope.reloadSuccess=false}, 1000);
- }
+ CollectionsV2.reloadCollection($scope.collection.name, {},
function(error, data,response) {
+ $timeout(function() {
+ if (error) {
+ $scope.reloadFailure = true;
+ $timeout(function() {$scope.reloadFailure=false}, 1000);
+ $location.path("/~collections");
+ } else {
+ $scope.reloadSuccess = true;
+ $timeout(function() {$scope.reloadSuccess=false}, 1000);
+ }
+ });
});
};
@@ -232,12 +251,11 @@ solrAdminApp.controller('CollectionsController',
shard.showAdd = !shard.showAdd;
delete $scope.addReplicaMessage;
- Zookeeper.liveNodes({}, function(data) {
- $scope.nodes = [];
- var children = data.tree[0].children;
- for (var child in children) {
- $scope.nodes.push(children[child].text);
- }
+ ClusterV2.listClusterNodes(function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.nodes = data.nodes;
+ });
});
};
@@ -252,38 +270,45 @@ solrAdminApp.controller('CollectionsController',
};
$scope.deleteShard = function(shard) {
- Collections.deleteShard({collection: shard.collection,
shard:shard.name}, function(data) {
- shard.deleted = true;
+ ShardsV2.deleteShard(shard.collection, shard.name, {},
function(error, data, response) {
$timeout(function() {
- $scope.refresh();
- }, 2000);
+ if (error) { ApiErrorHandler.handle(response); return; }
+ shard.deleted = true;
+ $timeout(function() {
+ $scope.refresh();
+ }, 2000);
+ });
});
}
$scope.deleteReplica = function(replica) {
- Collections.deleteReplica({collection: replica.collection,
shard:replica.shard, replica:replica.name}, function(data) {
- replica.deleted = true;
+ ReplicasV2.deleteReplicaByName(replica.collection, replica.shard,
replica.name, {}, function(error, data, response) {
$timeout(function() {
- $scope.refresh();
- }, 2000);
+ if (error) { ApiErrorHandler.handle(response); return; }
+ replica.deleted = true;
+ $timeout(function() {
+ $scope.refresh();
+ }, 2000);
+ });
});
}
$scope.addReplica = function(shard) {
- var params = {
- collection: shard.collection,
- shard: shard.name,
+ var createReplicaParams = {
type: shard.replicaType
}
if (shard.replicaNodeName && shard.replicaNodeName != "") {
- params.node = shard.replicaNodeName;
+ createReplicaParams.node = shard.replicaNodeName;
}
- Collections.addReplica(params, function(data) {
- shard.replicaAdded = true;
- $timeout(function () {
- shard.replicaAdded = false;
- shard.showAdd = false;
- $scope.refresh();
- }, 2000);
+ ReplicasV2.createReplica(shard.collection, shard.name,
{createReplicaRequestBody: createReplicaParams}, function(error, data,
response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ shard.replicaAdded = true;
+ $timeout(function () {
+ shard.replicaAdded = false;
+ shard.showAdd = false;
+ $scope.refresh();
+ }, 2000);
+ });
});
};
diff --git a/solr/webapp/web/js/angular/controllers/cores.js
b/solr/webapp/web/js/angular/controllers/cores.js
index 202b6224ca1..c6c6b311488 100644
--- a/solr/webapp/web/js/angular/controllers/cores.js
+++ b/solr/webapp/web/js/angular/controllers/cores.js
@@ -16,35 +16,39 @@
*/
solrAdminApp.controller('CoreAdminController',
- function($scope, $routeParams, $location, $timeout, $route, Cores, Update,
Constants){
+ function($scope, $routeParams, $location, $timeout, $route, CoresV2,
Update, Constants, ApiErrorHandler){
$scope.resetMenu("cores", Constants.IS_ROOT_PAGE);
$scope.selectedCore = $routeParams.corename; // use 'corename' not
'core' to distinguish from /solr/:core/
$scope.refresh = function() {
- Cores.get(function(data) {
- var coreCount = 0;
- var cores = data.status;
- for (_obj in cores) coreCount++;
- $scope.hasCores = coreCount >0;
- if (!$scope.selectedCore && coreCount==0) {
- $scope.showAddCore();
- return;
- } else if (!$scope.selectedCore) {
- for (firstCore in cores) break;
- $scope.selectedCore = firstCore;
- $location.path("/~cores/" + $scope.selectedCore).replace();
- }
- $scope.core = cores[$scope.selectedCore];
- $scope.corelist = [];
- $scope.swapCorelist = [];
- for (var core in cores) {
- $scope.corelist.push(cores[core]);
- if (cores[core] != $scope.core) {
- $scope.swapCorelist.push(cores[core]);
+ CoresV2.getAllCoreStatus({}, function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ var coreCount = 0;
+ var cores = data.status;
+ for (var _obj in cores) coreCount++;
+ $scope.hasCores = coreCount >0;
+ if (!$scope.selectedCore && coreCount==0) {
+ $scope.showAddCore();
+ return;
+ } else if (!$scope.selectedCore) {
+ var firstCore;
+ for (firstCore in cores) break;
+ $scope.selectedCore = firstCore;
+ $location.path("/~cores/" + $scope.selectedCore).replace();
}
- }
- if ($scope.swapCorelist.length>0) {
- $scope.swapOther = $scope.swapCorelist[0].name;
- }
+ $scope.core = cores[$scope.selectedCore];
+ $scope.corelist = [];
+ $scope.swapCorelist = [];
+ for (var core in cores) {
+ $scope.corelist.push(cores[core]);
+ if (cores[core] != $scope.core) {
+ $scope.swapCorelist.push(cores[core]);
+ }
+ }
+ if ($scope.swapCorelist.length>0) {
+ $scope.swapOther = $scope.swapCorelist[0].name;
+ }
+ });
});
};
$scope.showAddCore = function() {
@@ -65,9 +69,9 @@ solrAdminApp.controller('CoreAdminController',
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";
+ $scope.addMessage = "A core with that name already exists";
} else {
- var params = {
+ var createCoreParams = {
name: $scope.newCore.name,
instanceDir: $scope.newCore.instanceDir,
config: $scope.newCore.config,
@@ -75,12 +79,19 @@ solrAdminApp.controller('CoreAdminController',
dataDir: $scope.newCore.dataDir
};
if ($scope.isCloud) {
- params.collection = $scope.newCore.collection;
- params.shard = $scope.newCore.shard;
+ createCoreParams.collection = $scope.newCore.collection;
+ createCoreParams.shard = $scope.newCore.shard;
}
- Cores.add(params, function(data) {
- $location.path("/~cores/" + $scope.newCore.name);
- $scope.cancelAddCore();
+ CoresV2.createCore({createCoreParams: createCoreParams},
function(error, data, response) {
+ $timeout(function() {
+ if (error) {
+ ApiErrorHandler.handle(response);
+ $scope.addMessage = "Error creating core: " + error;
+ return;
+ }
+ $location.path("/~cores/" + $scope.newCore.name);
+ $scope.cancelAddCore();
+ });
});
}
};
@@ -93,8 +104,11 @@ solrAdminApp.controller('CoreAdminController',
$scope.unloadCore = function() {
var answer = confirm( 'Do you really want to unload Core "' +
$scope.selectedCore + '"?' );
if( !answer ) return;
- Cores.unload({core: $scope.selectedCore}, function(data) {
- $location.path("/~cores");
+ CoresV2.unloadCore($scope.selectedCore, {}, function(error, data,
response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $location.path("/~cores");
+ });
});
};
@@ -109,9 +123,16 @@ solrAdminApp.controller('CoreAdminController',
} else if ($scope.other == $scope.selectedCore) {
$scope.renameMessage = "New name must be different from the current
one";
} else {
- Cores.rename({core:$scope.selectedCore, other: $scope.other},
function(data) {
- $location.path("/~cores/" + $scope.other);
- $scope.cancelRename();
+ CoresV2.renameCore($scope.selectedCore, {renameCoreRequestBody: {to:
$scope.other}}, function(error, data, response) {
+ $timeout(function() {
+ if (error) {
+ ApiErrorHandler.handle(response);
+ $scope.renameMessage = "Error renaming core: " + error;
+ return;
+ }
+ $location.path("/~cores/" + $scope.other);
+ $scope.cancelRenameCore();
+ });
});
}
};
@@ -133,10 +154,17 @@ solrAdminApp.controller('CoreAdminController',
} else if ($scope.swapOther == $scope.selectedCore) {
$scope.swapMessage = "Cannot swap with the same core";
} else {
- Cores.swap({core: $scope.selectedCore, other: $scope.swapOther},
function(data) {
- $location.path("/~cores/" + $scope.swapOther);
- delete $scope.swapOther;
- $scope.cancelSwapCores();
+ CoresV2.swapCores($scope.selectedCore, {swapCoresRequestBody: {with:
$scope.swapOther}}, function(error, data, response) {
+ $timeout(function() {
+ if (error) {
+ ApiErrorHandler.handle(response);
+ $scope.swapMessage = "Error swapping cores: " + error;
+ return;
+ }
+ $location.path("/~cores/" + $scope.swapOther);
+ delete $scope.swapOther;
+ $scope.cancelSwapCores();
+ });
});
}
};
@@ -149,23 +177,25 @@ solrAdminApp.controller('CoreAdminController',
$scope.reloadCore = function() {
if ($scope.initFailures[$scope.selectedCore]) {
delete $scope.initFailures[$scope.selectedCore];
- $scope.showInitFailures = Object.keys(data.initFailures).length>0;
+ $scope.showInitFailures = Object.keys($scope.initFailures).length>0;
}
- Cores.reload({core: $scope.selectedCore},
- function(data) {
- if (data.error) {
- $scope.reloadFailure = true;
- $timeout(function() {
- $scope.reloadFailure = false;
- $route.reload();
- }, 1000);
- } else {
- $scope.reloadSuccess = true;
- $timeout(function () {
- $scope.reloadSuccess = false;
- $route.reload();
- }, 1000);
- }
+ CoresV2.reloadCore($scope.selectedCore,
+ function(error, data, response) {
+ $timeout(function() {
+ if (error) {
+ $scope.reloadFailure = true;
+ $timeout(function() {
+ $scope.reloadFailure = false;
+ $route.reload();
+ }, 1000);
+ } else {
+ $scope.reloadSuccess = true;
+ $timeout(function () {
+ $scope.reloadSuccess = false;
+ $route.reload();
+ }, 1000);
+ }
+ });
});
};
diff --git a/solr/webapp/web/js/angular/controllers/index.js
b/solr/webapp/web/js/angular/controllers/index.js
index eda5ea86c28..553724f1f4a 100644
--- a/solr/webapp/web/js/angular/controllers/index.js
+++ b/solr/webapp/web/js/angular/controllers/index.js
@@ -15,111 +15,114 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-solrAdminApp.controller('IndexController', function($scope, System, Cores,
Constants) {
+solrAdminApp.controller('IndexController', function($scope, $timeout,
SystemV2, Constants, ApiErrorHandler) {
$scope.resetMenu("index", Constants.IS_ROOT_PAGE);
$scope.reload = function() {
- System.get(function(data) {
- $scope.system = data;
- const releaseDate =
parse_release_date($scope.system.lucene['solr-impl-version'])
- $scope.releaseDaysOld = (new Date() - releaseDate)/1000/60/60/24;
-
- if (data.security.authenticationPlugin) {
- $scope.isSecurityEnabled = true
- }
-
- // load average, unless its negative (means n/a on windows, etc)
- if (data.system.systemLoadAverage >= 0) {
- $scope.load_average = data.system.systemLoadAverage.toFixed(2);
- }
-
- // physical memory
- var memoryMax = parse_memory_value(data.system.totalPhysicalMemorySize);
- $scope.memoryTotal =
parse_memory_value(data.system.totalPhysicalMemorySize -
data.system.freePhysicalMemorySize);
- $scope.memoryPercentage = ($scope.memoryTotal / memoryMax *
100).toFixed(1)+ "%";
- $scope.memoryMax = pretty_print_bytes(memoryMax);
- $scope.memoryTotalDisplay = pretty_print_bytes($scope.memoryTotal);
-
- // swap space
- var swapMax = parse_memory_value(data.system.totalSwapSpaceSize);
- $scope.swapTotal = parse_memory_value(data.system.totalSwapSpaceSize -
data.system.freeSwapSpaceSize);
- $scope.swapPercentage = ($scope.swapTotal / swapMax * 100).toFixed(1)+
"%";
- $scope.swapMax = pretty_print_bytes(swapMax);
- $scope.swapTotalDisplay = pretty_print_bytes($scope.swapTotal);
-
- // file handles
- $scope.fileDescriptorPercentage = (data.system.openFileDescriptorCount /
data.system.maxFileDescriptorCount *100).toFixed(1) + "%";
-
- // java memory
- var javaMemoryMax = parse_memory_value(data.jvm.memory.raw.max ||
data.jvm.memory.max);
- $scope.javaMemoryTotal = parse_memory_value(data.jvm.memory.raw.total ||
data.jvm.memory.total);
- $scope.javaMemoryUsed = parse_memory_value(data.jvm.memory.raw.used ||
data.jvm.memory.used);
- $scope.javaMemoryTotalPercentage = ($scope.javaMemoryTotal /
javaMemoryMax *100).toFixed(1) + "%";
- $scope.javaMemoryUsedPercentage = ($scope.javaMemoryUsed /
$scope.javaMemoryTotal *100).toFixed(1) + "%";
- $scope.javaMemoryPercentage = ($scope.javaMemoryUsed / javaMemoryMax *
100).toFixed(1) + "%";
- $scope.javaMemoryTotalDisplay =
pretty_print_bytes($scope.javaMemoryTotal);
- $scope.javaMemoryUsedDisplay =
pretty_print_bytes($scope.javaMemoryUsed); // @todo These should really be an
AngularJS Filter: {{ javaMemoryUsed | bytes }}
- $scope.javaMemoryMax = pretty_print_bytes(javaMemoryMax);
-
- // GPU
- $scope.gpuAvailable = data.gpu && data.gpu.available;
- if ($scope.gpuAvailable) {
- $scope.gpuCount = data.gpu.count;
-
- var devices = data.gpu.devices;
- $scope.gpuDevices = [];
- if (devices && Object.keys(devices).length > 0) {
- var deviceKeys = Object.keys(devices);
- var firstDevice = devices[deviceKeys[0]];
- $scope.gpuName = firstDevice.name;
- $scope.gpuId = firstDevice.id;
- $scope.gpuCompute = firstDevice.computeCapability;
-
- if (deviceKeys.length > 1) {
- $scope.gpuName += " (+" + (deviceKeys.length - 1) + " more)";
- }
+ SystemV2.getNodeSystemInfo({}, function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.system = data;
+ const releaseDate =
parse_release_date($scope.system.lucene['solr-impl-version'])
+ $scope.releaseDaysOld = (new Date() - releaseDate)/1000/60/60/24;
+
+ if (data.security.authenticationPlugin) {
+ $scope.isSecurityEnabled = true
+ }
- for (var i = 0; i < deviceKeys.length; i++) {
- var device = devices[deviceKeys[i]];
- var gpuData = {
- id: device.id,
- name: device.name,
- computeCapability: device.computeCapability,
- totalMemory: device.totalMemory,
- usedMemory: device.usedMemory,
- freeMemory: device.freeMemory,
- active: device.active
- };
-
- // Add "(active)" indicator to the name for active GPUs
- if (gpuData.active) {
- gpuData.name += " (active)";
+ // load average, unless its negative (means n/a on windows, etc)
+ if (data.system.systemLoadAverage >= 0) {
+ $scope.load_average = data.system.systemLoadAverage.toFixed(2);
+ }
+
+ // physical memory
+ var memoryMax =
parse_memory_value(data.system.totalPhysicalMemorySize);
+ $scope.memoryTotal =
parse_memory_value(data.system.totalPhysicalMemorySize -
data.system.freePhysicalMemorySize);
+ $scope.memoryPercentage = ($scope.memoryTotal / memoryMax *
100).toFixed(1)+ "%";
+ $scope.memoryMax = pretty_print_bytes(memoryMax);
+ $scope.memoryTotalDisplay = pretty_print_bytes($scope.memoryTotal);
+
+ // swap space
+ var swapMax = parse_memory_value(data.system.totalSwapSpaceSize);
+ $scope.swapTotal = parse_memory_value(data.system.totalSwapSpaceSize -
data.system.freeSwapSpaceSize);
+ $scope.swapPercentage = ($scope.swapTotal / swapMax * 100).toFixed(1)+
"%";
+ $scope.swapMax = pretty_print_bytes(swapMax);
+ $scope.swapTotalDisplay = pretty_print_bytes($scope.swapTotal);
+
+ // file handles
+ $scope.fileDescriptorPercentage = (data.system.openFileDescriptorCount
/ data.system.maxFileDescriptorCount *100).toFixed(1) + "%";
+
+ // java memory
+ var javaMemoryMax = parse_memory_value(data.jvm.memory.raw.max ||
data.jvm.memory.max);
+ $scope.javaMemoryTotal = parse_memory_value(data.jvm.memory.raw.total
|| data.jvm.memory.total);
+ $scope.javaMemoryUsed = parse_memory_value(data.jvm.memory.raw.used ||
data.jvm.memory.used);
+ $scope.javaMemoryTotalPercentage = ($scope.javaMemoryTotal /
javaMemoryMax *100).toFixed(1) + "%";
+ $scope.javaMemoryUsedPercentage = ($scope.javaMemoryUsed /
$scope.javaMemoryTotal *100).toFixed(1) + "%";
+ $scope.javaMemoryPercentage = ($scope.javaMemoryUsed / javaMemoryMax *
100).toFixed(1) + "%";
+ $scope.javaMemoryTotalDisplay =
pretty_print_bytes($scope.javaMemoryTotal);
+ $scope.javaMemoryUsedDisplay =
pretty_print_bytes($scope.javaMemoryUsed); // @todo These should really be an
AngularJS Filter: {{ javaMemoryUsed | bytes }}
+ $scope.javaMemoryMax = pretty_print_bytes(javaMemoryMax);
+
+ // GPU
+ $scope.gpuAvailable = data.gpu && data.gpu.available;
+ if ($scope.gpuAvailable) {
+ $scope.gpuCount = data.gpu.count;
+
+ var devices = data.gpu.devices;
+ $scope.gpuDevices = [];
+ if (devices && Object.keys(devices).length > 0) {
+ var deviceKeys = Object.keys(devices);
+ var firstDevice = devices[deviceKeys[0]];
+ $scope.gpuName = firstDevice.name;
+ $scope.gpuId = firstDevice.id;
+ $scope.gpuCompute = firstDevice.computeCapability;
+
+ if (deviceKeys.length > 1) {
+ $scope.gpuName += " (+" + (deviceKeys.length - 1) + " more)";
}
- // Only calculate memory display for active GPUs
- if (gpuData.active && gpuData.totalMemory && gpuData.usedMemory) {
- var total = parse_memory_value(gpuData.totalMemory);
- var used = parse_memory_value(gpuData.usedMemory);
- gpuData.memoryPercentage = (used / total * 100).toFixed(1) + "%";
- gpuData.totalMemoryDisplay = pretty_print_bytes(total);
- gpuData.usedMemoryDisplay = pretty_print_bytes(used);
+ for (var i = 0; i < deviceKeys.length; i++) {
+ var device = devices[deviceKeys[i]];
+ var gpuData = {
+ id: device.id,
+ name: device.name,
+ computeCapability: device.computeCapability,
+ totalMemory: device.totalMemory,
+ usedMemory: device.usedMemory,
+ freeMemory: device.freeMemory,
+ active: device.active
+ };
+
+ // Add "(active)" indicator to the name for active GPUs
+ if (gpuData.active) {
+ gpuData.name += " (active)";
+ }
+
+ // Only calculate memory display for active GPUs
+ if (gpuData.active && gpuData.totalMemory && gpuData.usedMemory)
{
+ var total = parse_memory_value(gpuData.totalMemory);
+ var used = parse_memory_value(gpuData.usedMemory);
+ gpuData.memoryPercentage = (used / total * 100).toFixed(1) +
"%";
+ gpuData.totalMemoryDisplay = pretty_print_bytes(total);
+ gpuData.usedMemoryDisplay = pretty_print_bytes(used);
+ }
+ $scope.gpuDevices.push(gpuData);
}
- $scope.gpuDevices.push(gpuData);
}
}
- }
-
- // no info bar:
- $scope.noInfo = !(
- data.system.totalPhysicalMemorySize &&
data.system.freePhysicalMemorySize &&
- data.system.totalSwapSpaceSize && data.system.freeSwapSpaceSize &&
- data.system.openFileDescriptorCount &&
data.system.maxFileDescriptorCount);
-
- // save a copy of the original commandline args
- $scope.commandLineArgsUnsorted = [...data.jvm.jmx.commandLineArgs];
- // get commandline args latest orderby or defaults to "Unsorted"
- $scope.commandLineOrderBy =
sessionStorage.getItem("commandline.orderby") || "Unsorted";
- $scope.showCommandLineArgs();
+
+ // no info bar:
+ $scope.noInfo = !(
+ data.system.totalPhysicalMemorySize &&
data.system.freePhysicalMemorySize &&
+ data.system.totalSwapSpaceSize && data.system.freeSwapSpaceSize &&
+ data.system.openFileDescriptorCount &&
data.system.maxFileDescriptorCount);
+
+ // save a copy of the original commandline args
+ $scope.commandLineArgsUnsorted = [...data.jvm.jmx.commandLineArgs];
+ // get commandline args latest orderby or defaults to "Unsorted"
+ $scope.commandLineOrderBy =
sessionStorage.getItem("commandline.orderby") || "Unsorted";
+ $scope.showCommandLineArgs();
});
+ });
};
$scope.toggleCommandLineOrder = function() {
$scope.commandLineOrderBy = ($scope.commandLineOrderBy=="Sorted") ?
"Unsorted":"Sorted";
diff --git a/solr/webapp/web/js/angular/controllers/logging.js
b/solr/webapp/web/js/angular/controllers/logging.js
index 6b38afe06ce..2011bf9f7d5 100644
--- a/solr/webapp/web/js/angular/controllers/logging.js
+++ b/solr/webapp/web/js/angular/controllers/logging.js
@@ -24,52 +24,55 @@ var format_time_content = function( time, timeZone ) {
}
solrAdminApp.controller('LoggingController',
- function($scope, $timeout, $cookies, Logging, Constants){
+ function($scope, $timeout, $cookies, LoggingV2, Constants, ApiErrorHandler){
$scope.resetMenu("logging", Constants.IS_ROOT_PAGE);
$scope.timezone = $cookies.logging_timezone || "Local";
$scope.refresh = function() {
- Logging.events(function(data) {
- $scope.since = new Date();
- $scope.sinceDisplay = format_time_content($scope.since, "Local");
- var events = data.history.docs;
- for (var i=0; i<events.length; i++) {
- var event = events[i];
- var time = new Date(event.time);
- event.local_time = format_time_content(time, "Local");
- event.utc_time = format_time_content(time, "UTC");
- event.loggerBase = event.logger.split( '.' ).pop();
+ LoggingV2.fetchLocalLogMessages({since: 0}, function(error, data,
response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.since = new Date();
+ $scope.sinceDisplay = format_time_content($scope.since, "Local");
+ var events = data.history;
+ for (var i=0; i<events.length; i++) {
+ var event = events[i];
+ var time = new Date(event.time);
+ event.local_time = format_time_content(time, "Local");
+ event.utc_time = format_time_content(time, "UTC");
+ event.loggerBase = event.logger.split( '.' ).pop();
- if( !event.trace ) {
- var lines = event.message.split( "\n" );
- if( lines.length > 1) {
- event.trace = event.message;
- event.message = lines[0];
+ if( !event.trace ) {
+ var lines = event.message.split( "\n" );
+ if( lines.length > 1) {
+ event.trace = event.message;
+ event.message = lines[0];
+ }
}
+ event.message = event.message.replace(/,/g, ',​');
+ event.showTrace = false;
}
- event.message = event.message.replace(/,/g, ',​');
- event.showTrace = false;
- }
- $scope.events = events;
- $scope.watcher = data.watcher;
- /* @todo sticky_mode
- // state element is in viewport
- sticky_mode = ( state.position().top <= $( window ).scrollTop() + $(
window ).height() - ( $( 'body' ).height() - state.position().top ) );
- // initial request
- if( 0 === since ) {
- sticky_mode = true;
- }
- $scope.loggingEvents = events;
+ $scope.events = events;
+ $scope.watcher = data.watcher;
+ /* @todo sticky_mode
+ // state element is in viewport
+ sticky_mode = ( state.position().top <= $( window ).scrollTop() + $(
window ).height() - ( $( 'body' ).height() - state.position().top ) );
+ // initial request
+ if( 0 === since ) {
+ sticky_mode = true;
+ }
+ $scope.loggingEvents = events;
- if( sticky_mode )
- {
- $( 'body' )
- .animate
- (
- { scrollTop: state.position().top },
- 1000
- );
- }
- */
+ if( sticky_mode )
+ {
+ $( 'body' )
+ .animate
+ (
+ { scrollTop: state.position().top },
+ 1000
+ );
+ }
+ */
+ });
});
$scope.timeout = $timeout($scope.refresh, 10000);
var onRouteChangeOff = $scope.$on('$routeChangeStart', function() {
@@ -98,7 +101,7 @@ solrAdminApp.controller('LoggingController',
)
.controller('LoggingLevelController',
- function($scope, Logging) {
+ function($scope, $timeout, Logging, LoggingV2, ApiErrorHandler) {
$scope.resetMenu("logging-levels");
var packageOf = function(logger) {
@@ -123,13 +126,16 @@ solrAdminApp.controller('LoggingController',
};
$scope.refresh = function() {
- Logging.levels(function(data) {
- $scope.logging = makeTree(data.loggers, "");
- $scope.watcher = data.watcher;
- $scope.levels = [];
- for (level in data.levels) {
- $scope.levels.push({name:data.levels[level], pos:level});
- }
+ LoggingV2.listAllLoggersAndLevels(function(error, data, response) {
+ $timeout(function() {
+ if (error) { ApiErrorHandler.handle(response); return; }
+ $scope.logging = makeTree(data.loggers, "");
+ $scope.watcher = data.watcher;
+ $scope.levels = [];
+ for (var level in data.levels) {
+ $scope.levels.push({name:data.levels[level], pos:level});
+ }
+ });
});
};
@@ -155,6 +161,10 @@ solrAdminApp.controller('LoggingController',
}
var setString = logger.name + ":" + newLevel;
logger.showOptions = false;
+ // Intentionally still v1 (Logging, not LoggingV2): this relies on the
"nodes=all" param to
+ // broadcast the level change to every live node. The v2 NodeLoggingApis
endpoint is
+ // single-node only until SOLR-16738 wires it up to the new
V2SolrRequestBasedProxy (see the
+ // TODO in NodeLogging.java). Move this to LoggingV2.modifyLocalLogLevel
once that lands.
Logging.setLevel({set: setString}, function(data) {
$scope.refresh();
});
diff --git a/solr/webapp/web/js/angular/controllers/login.js
b/solr/webapp/web/js/angular/controllers/login.js
index aead23a4e37..02fa6c3b6d6 100644
--- a/solr/webapp/web/js/angular/controllers/login.js
+++ b/solr/webapp/web/js/angular/controllers/login.js
@@ -147,6 +147,8 @@ solrAdminApp.controller('LoginController',
}
if (errorText === "") {
+ // The V2 solrApi client picks these up automatically via the
superagent plugin
+ // registered in app.js .config()
sessionStorage.setItem("auth.username", payload['sub']);
sessionStorage.setItem("auth.header", "Bearer " + accessToken);
sessionStorage.removeItem("auth.statusText");
diff --git a/solr/webapp/web/js/angular/controllers/paramsets.js
b/solr/webapp/web/js/angular/controllers/paramsets.js
index e18870b3ce3..d466c31a8a6 100644
--- a/solr/webapp/web/js/angular/controllers/paramsets.js
+++ b/solr/webapp/web/js/angular/controllers/paramsets.js
@@ -33,6 +33,13 @@ solrAdminApp.controller('ParamSetsController',
}
}
+ // The v2 config/params API needs to know up front whether ":core" is a
collection name
+ // (SolrCloud) or an actual core name (standalone/user-managed) -- there's
no equivalent of
+ // v1's flexible core-or-collection routing.
+ $scope.paramSetIndexType = function() {
+ return $scope.isCloudEnabled ? "collections" : "cores";
+ }
+
$scope.selectParamset = function() {
$location.search("paramset", $scope.name);
$scope.getParamset($scope.name);
@@ -43,6 +50,7 @@ solrAdminApp.controller('ParamSetsController',
var params = {};
params.core = $routeParams.core;
+ params.indexType = $scope.paramSetIndexType();
params.wt = "json";
params.name = paramset;
@@ -76,6 +84,7 @@ solrAdminApp.controller('ParamSetsController',
var params = {};
params.core = $routeParams.core;
+ params.indexType = $scope.paramSetIndexType();
params.wt = "json";
ParamSet.get(params, callback, failure);
@@ -95,11 +104,18 @@ solrAdminApp.controller('ParamSetsController',
}
}
- $scope.getParamsets();
- if ($routeParams.paramset){
- $scope.name = $routeParams.paramset;
- $scope.getParamset($routeParams.paramset);
- }
+ // resetMenu() above populates $scope.isCloudEnabled asynchronously, so
calling
+ // getParamsets() synchronously here would race it and fall back to
indexType "cores"
+ // even in SolrCloud -- wait for isCloudEnabled to settle before the first
fetch.
+ var unwatchCloudEnabled = $scope.$watch('isCloudEnabled', function(value) {
+ if (value === undefined) return;
+ unwatchCloudEnabled();
+ $scope.getParamsets();
+ if ($routeParams.paramset){
+ $scope.name = $routeParams.paramset;
+ $scope.getParamset($routeParams.paramset);
+ }
+ });
$scope.refresh = function () {
$scope.paramsetContent = "";
@@ -108,9 +124,17 @@ solrAdminApp.controller('ParamSetsController',
$scope.refresh();
$scope.submit = function () {
+ if (!$scope.paramsetContent || !$scope.paramsetContent.trim()) {
+ $scope.responseStatus = "error";
+ $scope.response = "Please enter a Paramset(s) JSON payload before
submitting. " +
+ "(Checking \"Sample Paramset\" only shows an example -- copy it into
the text area to use it.)";
+ return;
+ }
+
var params = {};
params.core = $routeParams.core;
+ params.indexType = $scope.paramSetIndexType();
params.wt = "json";
ParamSet.submit(params, $scope.paramsetContent, callback, failure);
@@ -133,8 +157,8 @@ solrAdminApp.controller('ParamSetsController',
var params = {};
params.core = $routeParams.core;
+ params.indexType = $scope.paramSetIndexType();
params.wt = "json";
- params.name = $scope.name;
var apiPayload = {
"delete": [$scope.name]
diff --git a/solr/webapp/web/js/angular/controllers/query.js
b/solr/webapp/web/js/angular/controllers/query.js
index 33294b81097..1d135e2069c 100644
--- a/solr/webapp/web/js/angular/controllers/query.js
+++ b/solr/webapp/web/js/angular/controllers/query.js
@@ -30,12 +30,22 @@ solrAdminApp.controller('QueryController',
$scope.val['indent'] = true;
$scope.useParams = [];
- getParamsets();
+ // isCloudEnabled populates asynchronously via resetMenu(), so calling
getParamsets()
+ // synchronously here would race it and fall back to indexType "cores"
even in SolrCloud --
+ // wait for isCloudEnabled to settle before the first fetch (see
paramsets.js for the same fix).
+ var unwatchCloudEnabled = $scope.$watch('isCloudEnabled', function(value) {
+ if (value === undefined) return;
+ unwatchCloudEnabled();
+ getParamsets();
+ });
function getParamsets() {
var params = {};
params.core = $routeParams.core;
+ // The v2 config/params API needs to know up front whether ":core" is a
collection name
+ // (SolrCloud) or an actual core name (standalone/user-managed); see
paramsets.js for details.
+ params.indexType = $scope.isCloudEnabled ? "collections" : "cores";
params.wt = "json";
ParamSet.get(params, callback, failure);
diff --git a/solr/webapp/web/js/angular/controllers/security.js
b/solr/webapp/web/js/angular/controllers/security.js
index 9dec02f8d02..1bbfd3511ab 100644
--- a/solr/webapp/web/js/angular/controllers/security.js
+++ b/solr/webapp/web/js/angular/controllers/security.js
@@ -15,7 +15,7 @@
limitations under the License.
*/
-solrAdminApp.controller('SecurityController', function ($scope, $timeout,
$cookies, $window, Constants, System, Security) {
+solrAdminApp.controller('SecurityController', function ($scope, $timeout,
$cookies, $window, Constants, SystemV2, Security, ApiErrorHandler) {
$scope.resetMenu("security", Constants.IS_ROOT_PAGE);
$scope.params = [];
@@ -324,21 +324,27 @@ solrAdminApp.controller('SecurityController', function
($scope, $timeout, $cooki
$scope.permFilterOptions = [];
$scope.permFilterTypes = ["", "name", "role", "path", "collection"];
- System.get(function(data) {
- $scope.tls = data.security ? data.security["tls"] : false;
- $scope.authenticationPlugin = data.security ?
data.security["authenticationPlugin"] : null;
- $scope.authorizationPlugin = data.security ?
data.security["authorizationPlugin"] : null;
- $scope.isSecurityAdminEnabled = $scope.authenticationPlugin != null;
- $scope.isCloudMode = data.mode.match( /solrcloud/i ) != null;
- $scope.zkHost = $scope.isCloudMode ? data["zkHost"] : "";
- $scope.solrHome = data["solr_home"];
- $scope.refreshSecurityPanel();
- }, function(e) {
- if (e.status === 401 || e.status === 403) {
- $scope.isSecurityAdminEnabled = true;
- $scope.hasSecurityEditPerm = false;
- $scope.hideAll();
- }
+ SystemV2.getNodeSystemInfo({}, function(error, data, response) {
+ $timeout(function() {
+ if (error) {
+ if (response && (response.status === 401 || response.status ===
403)) {
+ $scope.isSecurityAdminEnabled = true;
+ $scope.hasSecurityEditPerm = false;
+ $scope.hideAll();
+ } else {
+ ApiErrorHandler.handle(response);
+ }
+ return;
+ }
+ $scope.tls = data.security ? data.security["tls"] : false;
+ $scope.authenticationPlugin = data.security ?
data.security["authenticationPlugin"] : null;
+ $scope.authorizationPlugin = data.security ?
data.security["authorizationPlugin"] : null;
+ $scope.isSecurityAdminEnabled = $scope.authenticationPlugin != null;
+ $scope.isCloudMode = data.mode.match( /solrcloud/i ) != null;
+ $scope.zkHost = $scope.isCloudMode ? data["zkHost"] : "";
+ $scope.solrHome = data["solr_home"];
+ $scope.refreshSecurityPanel();
+ });
});
};
@@ -403,7 +409,7 @@ solrAdminApp.controller('SecurityController', function
($scope, $timeout, $cooki
// check for issues with perm config
$scope.validatePermConfig();
- // use the current user's roles (obtained from System.get) to check if
they have the security permissions
+ // use the current user's roles (obtained from
SystemV2.getNodeSystemInfo) to check if they have the security permissions
// Note: the backend will check too so this is only for display purposes
$scope.hasSecurityEditPerm =
$scope.isPermitted(permissions.SECURITY_EDIT_PERM);
$scope.hasSecurityReadPerm = $scope.hasSecurityEditPerm ||
$scope.isPermitted(permissions.SECURITY_READ_PERM);
diff --git a/solr/webapp/web/js/angular/controllers/segments.js
b/solr/webapp/web/js/angular/controllers/segments.js
index e835cc08496..7043bae5a98 100644
--- a/solr/webapp/web/js/angular/controllers/segments.js
+++ b/solr/webapp/web/js/angular/controllers/segments.js
@@ -17,41 +17,47 @@
var MB_FACTOR = 1024*1024;
-solrAdminApp.controller('SegmentsController', function($scope, $routeParams,
$interval, Segments, Constants) {
+solrAdminApp.controller('SegmentsController', function($scope, $routeParams,
$interval, $timeout, SegmentsV2, Constants, ApiErrorHandler) {
$scope.resetMenu("segments", Constants.IS_CORE_PAGE);
$scope.refresh = function() {
- Segments.get({core: $routeParams.core}, function(data) {
- var segments = data.segments;
-
- var segmentSizeInBytesMax = getLargestSegmentSize(segments);
- $scope.segmentMB = Math.floor(segmentSizeInBytesMax / MB_FACTOR);
- $scope.xaxis = calculateXAxis(segmentSizeInBytesMax);
+ SegmentsV2.getSegmentData($routeParams.core, {}, function(error, data,
response) {
+ if (error) {
+ console.error('Failed to fetch segment data:', error);
+ ApiErrorHandler.handle(response);
+ return;
+ }
+ $timeout(function() {
+ var segments = data.segments;
- $scope.documentCount = 0;
- $scope.deletionCount = 0;
+ var segmentSizeInBytesMax = getLargestSegmentSize(segments);
+ $scope.segmentMB = Math.floor(segmentSizeInBytesMax / MB_FACTOR);
+ $scope.xaxis = calculateXAxis(segmentSizeInBytesMax);
- $scope.segments = [];
- for (var name in segments) {
- var segment = segments[name];
+ $scope.documentCount = 0;
+ $scope.deletionCount = 0;
- var segmentSizeInBytesLog = Math.log(segment.sizeInBytes);
- var segmentSizeInBytesMaxLog = Math.log(segmentSizeInBytesMax);
+ $scope.segments = [];
+ for (var name in segments) {
+ var segment = segments[name];
- segment.totalSize = Math.floor((segmentSizeInBytesLog /
segmentSizeInBytesMaxLog ) * 100);
+ var segmentSizeInBytesLog = Math.log(segment.sizeInBytes);
+ var segmentSizeInBytesMaxLog =
Math.log(segmentSizeInBytesMax);
- segment.deletedDocSize = Math.floor((segment.delCount /
segment.size) * segment.totalSize);
- if (segment.delDocSize <= 0.001) delete segment.deletedDocSize;
+ segment.totalSize = Math.floor((segmentSizeInBytesLog /
segmentSizeInBytesMaxLog ) * 100);
- segment.aliveDocSize = segment.totalSize -
segment.deletedDocSize;
+ segment.deletedDocSize = Math.floor((segment.delCount /
segment.size) * segment.totalSize);
+ segment.aliveDocSize = segment.totalSize -
segment.deletedDocSize;
+ if (segment.deletedDocSize <= 0.001) delete
segment.deletedDocSize;
- $scope.segments.push(segment);
+ $scope.segments.push(segment);
- $scope.documentCount += segment.size;
- $scope.deletionCount += segment.delCount;
- }
- $scope.deletionsPercentage =
calculateDeletionsPercentage($scope.documentCount, $scope.deletionCount);
+ $scope.documentCount += segment.size;
+ $scope.deletionCount += segment.delCount;
+ }
+ $scope.deletionsPercentage =
calculateDeletionsPercentage($scope.documentCount, $scope.deletionCount);
+ });
});
};
diff --git a/solr/webapp/web/js/angular/services.js
b/solr/webapp/web/js/angular/services.js
index 47c5ad2fa6e..f75a2f9d3c6 100644
--- a/solr/webapp/web/js/angular/services.js
+++ b/solr/webapp/web/js/angular/services.js
@@ -17,11 +17,7 @@
var solrAdminServices = angular.module('solrAdminServices', ['ngResource']);
-solrAdminServices.factory('System',
- ['$resource', function($resource) {
- return $resource('admin/info/system', {"wt":"json", "nodes": "@nodes",
"_":Date.now()});
- }])
-.factory('Metrics',
+solrAdminServices.factory('Metrics',
['$resource', 'PrometheusParser', function($resource, PrometheusParser) {
return $resource('admin/metrics', {"wt":"prometheus", "node": "@node",
"_":Date.now()}, {
get: {
@@ -44,35 +40,124 @@ solrAdminServices.factory('System',
}
});
}])
+.factory('ApiErrorHandler',
+ ['$rootScope', '$location', '$timeout', function($rootScope, $location,
$timeout) {
+ // v2 API calls go through the generated OpenAPI client, which uses
superagent directly and
+ // so never passes through Angular's $http -- meaning httpInterceptor in
app.js (the global
+ // error banner, 401 redirect, 403 handling) never fires for them. This
mirrors
+ // httpInterceptor's responseError handling for v2's superagent
responses, so a failure looks
+ // the same to the user regardless of which API generation served it.
Call from any v2
+ // callback's error branch: `if (error) {
ApiErrorHandler.handle(response); return; }`
+ function handle(response) {
+ if (!response) {
+ return;
+ }
+ // superagent callbacks fire outside Angular's digest cycle, so
changes here are invisible
+ // until the next digest -- $timeout both defers and triggers one.
+ $timeout(function() {
+ if (response.status === 401) {
+ var headers = response.headers || {};
+ sessionStorage.setItem("auth.wwwAuthHeader",
headers['www-authenticate']);
+ sessionStorage.setItem("auth.authDataHeader",
headers['x-solr-authdata']);
+ sessionStorage.setItem("auth.statusText", response.statusText);
+ sessionStorage.setItem("http401", "true");
+ sessionStorage.removeItem("auth.scheme");
+ sessionStorage.removeItem("auth.realm");
+ sessionStorage.removeItem("auth.username");
+ sessionStorage.removeItem("auth.header");
+ sessionStorage.removeItem("auth.state");
+ if ($location.path().includes('/login')) {
+ if (!sessionStorage.getItem("auth.location")) {
+ sessionStorage.setItem("auth.location", "/");
+ }
+ } else {
+ sessionStorage.setItem("auth.location", $location.path());
+ $location.path('/login');
+ }
+ } else if (response.status === 403) {
+ $rootScope.showAuthzFailures = true;
+ } else {
+ var url = (response.req && response.req.url) || (response.status +
' ' + $location.url());
+ var body = response.body || {};
+ var msg = (body.error && body.error.msg) || response.statusText ||
"Unknown error";
+ // MainController normally sets this up first, but don't assume
that ordering here.
+ $rootScope.exceptions = $rootScope.exceptions || {};
+ $rootScope.exceptions[url] = {msg: msg};
+ }
+ });
+ }
+ return {handle: handle};
+ }])
.factory('CollectionsV2',
function() {
solrApi.ApiClient.instance.basePath = '/api';
delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
return new solrApi.CollectionsApi();
})
+.factory('CoresV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.CoresApi();
+ })
+.factory('LoggingV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.LoggingApi();
+ })
+.factory('SystemV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.SystemApi();
+ })
+.factory('AliasesV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.AliasesApi();
+ })
+.factory('ShardsV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.ShardsApi();
+ })
+.factory('ReplicasV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.ReplicasApi();
+ })
+.factory('ConfigSetsV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.ConfigsetsApi();
+ })
+.factory('ClusterV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.ClusterApi();
+ })
+.factory('SegmentsV2',
+ function() {
+ solrApi.ApiClient.instance.basePath = '/api';
+ delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"];
+ return new solrApi.SegmentsApi();
+ })
.factory('Collections',
- ['$resource', function($resource) {
- return $resource('admin/collections',
- {'wt':'json', '_':Date.now()}, {
- "list": {params:{action: "LIST"}},
- "listaliases": {params:{action: "LISTALIASES"}},
- "status": {params:{action: "CLUSTERSTATUS"}},
- "add": {params:{action: "CREATE"}},
- "delete": {params:{action: "DELETE"}},
- "rename": {params:{action: "RENAME"}},
- "createAlias": {params:{action: "CREATEALIAS"}},
- "deleteAlias": {params:{action: "DELETEALIAS"}},
- "deleteReplica": {params:{action: "DELETEREPLICA"}},
- "addReplica": {params:{action: "ADDREPLICA"}},
- "deleteShard": {params:{action: "DELETESHARD"}},
- "reload": {method: "GET", params:{action:"RELOAD", core: "@core"}}
+ ['$resource', function ($resource) {
+ // v2 ClusterAPI (/api/cluster) delegates straight through to the same v1
CollectionsHandler
+ // that v1's CLUSTERSTATUS action used, so the response shape is
byte-identical -- no
+ // generated solrApi client class exists for it (old-style @EndPoint API,
predates the
+ // OpenAPI-based v2 framework), so this stays a plain $resource, like
Threads/ParamSet.
+ return $resource('/api/cluster', {'wt':'json', '_':Date.now()}, {
+ "status": {}
});
}])
-.factory('ConfigSets',
- ['$resource', function ($resource) {
- return $resource('admin/configs', {'wt': 'json', '_': Date.now()},
{"configs": {params: {action: "LIST"}}
- });
- }])
.factory('ConfigSetFiles',
['$http', function ($http) {
// Fetches a single file from a configset via V2
/api/configsets/{name}/files/{path}.
@@ -90,24 +175,12 @@ solrAdminServices.factory('System',
}
};
}])
-.factory('Cores',
- ['$resource', function($resource) {
- return $resource('admin/cores',
- {'wt':'json', '_':Date.now()}, {
- "query": {},
- "list": {params:{indexInfo: false}},
- "add": {params:{action: "CREATE"}},
- "unload": {params:{action: "UNLOAD", core: "@core"}},
- "rename": {params:{action: "RENAME"}},
- "swap": {params:{action: "SWAP"}},
- "reload": {method: "GET", params:{action:"RELOAD", core: "@core"},
headers:{doNotIntercept: "true"}}
- });
- }])
.factory('Logging',
['$resource', function($resource) {
+ // This v1 factory only covers "setLevel", which needs the "nodes=all"
broadcast-to-every-node
+ // behavior that the v2 NodeLoggingApis endpoint doesn't support yet (see
SOLR-16738). Retire
+ // this factory once setLevel moves to LoggingV2.
return $resource('admin/info/logging', {'wt':'json', '_':Date.now()}, {
- "events": {params: {since:'0'}},
- "levels": {},
"setLevel": {params: {nodes:'all'}}
});
}])
@@ -132,11 +205,11 @@ solrAdminServices.factory('System',
}])
.factory('Threads',
['$resource', function($resource) {
- return $resource('admin/info/threads', {'wt':'json', '_':Date.now()});
- }])
-.factory('Properties',
- ['$resource', function($resource) {
- return $resource('admin/info/properties', {'wt':'json', '_':Date.now()});
+ // v2 NodeThreadsAPI (/api/node/threads) still just delegates straight
through to the same v1
+ // ThreadDumpHandler, so the response shape is byte-identical -- no
generated solrApi client
+ // class exists for it (it predates the OpenAPI-based v2 API framework),
so this stays a plain
+ // $resource, like SchemaDesigner/Security.
+ return $resource('/api/node/threads', {'wt':'json', '_':Date.now()});
}])
.factory('Replication',
['$resource', function($resource) {
@@ -161,7 +234,16 @@ solrAdminServices.factory('System',
}])
.factory('ParamSet',
['$resource', function($resource) {
- return $resource(':core/config/params/:name', {core: '@core', wt:'json',
_:Date.now()}, {
+ // v2 GetConfigAPI/ModifyParamSetAPI
(/api/(cores|collections)/:core/config/params) still
+ // delegate straight through to the same v1 SolrConfigHandler, so the
response shape is
+ // byte-identical -- no generated solrApi client class exists for it
(old-style @EndPoint API,
+ // predates the OpenAPI-based v2 framework), so this stays a plain
$resource, like Threads.
+ // NB: unlike v1's flexible routing, the v2 API requires knowing up front
whether ":core" is a
+ // collection name (SolrCloud) or an actual core name
(standalone/user-managed) --
+ // /api/collections/... 500s in standalone mode (it tries to resolve
aliases, which needs ZK),
+ // and there's no such thing as a "collection" there anyway. Callers must
pass "indexType" as
+ // "collections" or "cores" (see paramsets.js, driven by
$scope.isCloudEnabled).
+ return $resource('/api/:indexType/:core/config/params/:name', {core:
'@core', indexType: '@indexType', wt:'json', _:Date.now()}, {
"submit": {headers: {'Content-type': 'application/json'}, method:
"POST"},
"get": {headers: {'Content-type': 'application/json'}, method: "GET"}
});
@@ -266,12 +348,6 @@ solrAdminServices.factory('System',
}
return resource;
}])
-.factory('Segments',
- ['$resource', function($resource) {
- return $resource(':core/admin/segments', {'wt':'json', core: '@core',
_:Date.now()}, {
- get: {}
- });
-}])
.factory('Schema',
['$resource', function($resource) {
return $resource(':core/schema', {wt: 'json', core: '@core',
_:Date.now()}, {
@@ -378,6 +454,8 @@ solrAdminServices.factory('System',
service.SetCredentials = function (username, password) {
var authdata = base64.encode(username + ':' + password);
+ // The V2 solrApi client picks this up automatically via the
superagent plugin
+ // registered in app.js .config().
sessionStorage.setItem("auth.header", "Basic " + authdata);
sessionStorage.setItem("auth.username", username);
};