diff --git a/partials/plugins.html b/partials/plugins.html new file mode 100644 index 00000000000..d95fc9b32dd --- /dev/null +++ b/partials/plugins.html @@ -0,0 +1,72 @@ + +
+ +
+ +
+ + + +
+
+ +

Watching for Changes

+ + +
+
+
+ +
diff --git a/solr/webapp/web/css/angular/plugins.css b/solr/webapp/web/css/angular/plugins.css new file mode 100644 index 00000000000..0310e0e5d54 --- /dev/null +++ b/solr/webapp/web/css/angular/plugins.css @@ -0,0 +1,212 @@ +/* + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#content #plugins #navigation +{ + width: 20%; +} + +#content #plugins #navigation .cache a { background-image: url( ../../img/ico/disk-black.png ); } +#content #plugins #navigation .core a { background-image: url( ../../img/ico/wooden-box.png ); } +#content #plugins #navigation .other a { background-image: url( ../../img/ico/zone.png ); } +#content #plugins #navigation .highlighting a { background-image: url( ../../img/ico/highlighter-text.png ); } +#content #plugins #navigation .updatehandler a{ background-image: url( ../../img/ico/arrow-circle.png ); } +#content #plugins #navigation .queryhandler a { background-image: url( ../../img/ico/magnifier.png ); } +#content #plugins #navigation .queryparser a { background-image: url( ../../img/ico/asterisk.png ); } + +#content #plugins #navigation .PLUGINCHANGES { margin-top: 20px; } +#content #plugins #navigation .PLUGINCHANGES a { background-image: url( ../../img/ico/eye.png ); } +#content #plugins #navigation .RELOAD a { background-image: url( ../../img/ico/arrow-circle.png ); } + + +#content #plugins #navigation a +{ + position: relative; +} + +#content #plugins #navigation a span +{ + background-color: #bba500; + border-radius: 5px; + color: #fff; + font-size: 10px; + font-weight: normal; + line-height: 1.4em; + padding-left: 4px; + padding-right: 4px; + position: absolute; + right: 5px; + top: 7px; +} + +#content #plugins #frame +{ + float: right; + width: 78%; +} + +#content #plugins #frame .entry +{ + margin-bottom: 10px; +} + +#content #plugins #frame .entry:last-child +{ + margin-bottom: 0; +} + +#content #plugins #frame .entry a +{ + background-image: url( ../../img/ico/chevron-small-expand.png ); + background-position: 0 50%; + display: block; + font-weight: bold; + padding-left: 21px; +} + +#content #plugins #frame .entry.changed a span +{ + color: #bba500; +} + +#content #plugins #frame .entry.expanded a +{ + background-image: url( ../../img/ico/chevron-small.png ); +} + +#content #plugins #frame .entry.expanded ul +{ + display: block; +} + +#content #plugins #frame .entry ul +{ + border-left: 9px solid #f0f3ff; + margin-left: 3px; + padding-top: 5px; + padding-left: 10px; +} + +#content #plugins #frame .entry li +{ + padding-top: 2px; + padding-bottom: 2px; +} + +#content #plugins #frame .entry li.stats +{ + border-top: 1px solid #c0c0c0; + margin-top: 5px; + padding-top: 5px; +} + +#content #plugins #frame .entry li.odd +{ + background-color: #f8f8f8; +} + +#content #plugins #frame .entry dt, +#content #plugins #frame .entry .stats span +{ + float: left; + width: 11%; +} + +#content #plugins #frame .entry dd, +#content #plugins #frame .entry .stats ul +{ + float: right; + width: 88%; +} + +#content #plugins #frame .entry .stats ul +{ + border-left: 0; + margin: 0; + padding: 0; +} + +#content #plugins #frame .entry .stats dt +{ + width: 27%; +} + +#content #plugins #frame .entry .stats dd +{ + width: 72%; +} + +#content #plugins #frame .entry.expanded a.linker { + background-image: none; + background-position: 0 0; + display: inline; + font-weight: normal; + padding:0px; +} + +#content #plugins #frame .entry.expanded a.linker:hover { + background-color:#F0F3FF; +} + +#recording #blockUI +{ + position: absolute; + left:0; + top:0; + width: 100%; + height: 100%; + background-color: #000; + opacity: 0.6; + z-index:1000; + padding:0; +} + +#recording .wrapper +{ + position: absolute; + top: 50%; + left: 50%; + padding: 30px; + width: 415px; + height: 100px; + border: 2px solid black; + background-color: #FFF; + opacity: 1; + z-index: 2000; + transform: translate(-50%, -50%); +} + +#recording p +{ + background-position: 0 50%; + float: left; + padding-left: 21px; + padding-top: 7px; + padding-bottom: 7px; +} + +#recording button +{ + float: right; +} + +#recording button span +{ + background-image: url( ../../img/ico/new-text.png ); +} diff --git a/solr/webapp/web/index.html b/solr/webapp/web/index.html index b5e0a9e59e6..b51db287938 100644 --- a/solr/webapp/web/index.html +++ b/solr/webapp/web/index.html @@ -34,7 +34,7 @@ limitations under the License. - + @@ -66,6 +66,7 @@ limitations under the License. + diff --git a/solr/webapp/web/js/angular/app.js b/solr/webapp/web/js/angular/app.js index e76febcc83d..b6969d46ae5 100644 --- a/solr/webapp/web/js/angular/app.js +++ b/solr/webapp/web/js/angular/app.js @@ -75,6 +75,16 @@ solrAdminApp.config([ templateUrl: 'partials/files.html', controller: 'FilesController' }). + when('/:core/plugins', { + templateUrl: 'partials/plugins.html', + controller: 'PluginsController', + reloadOnSearch: false + }). + when('/:core/plugins/:legacytype', { + templateUrl: 'partials/plugins.html', + controller: 'PluginsController', + reloadOnSearch: false + }). when('/:core/query', { templateUrl: 'partials/query.html', controller: 'QueryController' diff --git a/solr/webapp/web/js/angular/controllers/plugins.js b/solr/webapp/web/js/angular/controllers/plugins.js new file mode 100644 index 00000000000..f80f0dfdeb1 --- /dev/null +++ b/solr/webapp/web/js/angular/controllers/plugins.js @@ -0,0 +1,166 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +solrAdminApp.controller('PluginsController', + function($scope, $rootScope, $routeParams, $location, Mbeans) { + $scope.resetMenu("plugins"); + + if ($routeParams.legacytype) { + // support legacy URLs. Angular cannot change #path without reloading controller + $location.path("/"+$routeParams.core+"/plugins"); + $location.search("type", $routeParams.legacytype); + return; + } + + $scope.refresh = function() { + Mbeans.stats({core: $routeParams.core}, function (data) { + var type = $location.search().type; + $scope.types = getPluginTypes(data, type); + $scope.type = getSelectedType($scope.types, type); + + if ($scope.type && $routeParams.entry) { + $scope.plugins = $routeParams.entry.split(","); + openPlugins($scope.type, $scope.plugins); + } else { + $scope.plugins = []; + } + }); + }; + + $scope.selectPluginType = function(type) { + $location.search({entry:null, type: type.lower}); + $scope.type = type; + }; + + $scope.selectPlugin = function(plugin) { + plugin.open = !plugin.open; + + if (plugin.open) { + $scope.plugins.push(plugin.name); + } else { + $scope.plugins.splice($scope.plugins.indexOf(plugin.name), 1); + } + + if ($scope.plugins.length==0) { + $location.search("entry", null); + } else { + $location.search("entry", $scope.plugins.join(',')); + } + } + + $scope.startRecording = function() { + $scope.isRecording = true; + Mbeans.reference({core: $routeParams.core}, function(data) { + $scope.reference = data.reference; + console.log($scope.reference); + }) + } + + $scope.stopRecording = function() { + $scope.isRecording = false; + console.log($scope.reference); + Mbeans.delta({core: $routeParams.core}, $scope.reference, function(data) { + parseDelta($scope.types, data); + }); + } + + $scope.refresh(); + }); + +var getPluginTypes = function(data, selected) { + var keys = []; + var mbeans = data["solr-mbeans"]; + for (var i=0; i b.name}); + return keys; +}; + +var getPlugins = function(data) { + var plugins = []; + for (var key in data) { + var pluginProperties = data[key]; + var stats = pluginProperties.stats; + delete pluginProperties.stats; + for (var stat in stats) { + // add breaking space after a bracket or @ to handle wrap long lines: + stats[stat] = new String(stats[stat]).replace( /([\(@])/g, '$1​'); + } + plugin = {name: key, changed: false, stats: stats, open:false}; + plugin.properties = pluginProperties; + plugins.push(plugin); + } + plugins.sort(function(a,b) {return a.name > b.name}); + return plugins; +}; + +var getSelectedType = function(types, selected) { + if (selected) { + for (var i in types) { + if (types[i].lower == selected) { + return types[i]; + } + } + } +}; + +var parseDelta = function(types, data) { + + var getByName = function(list, name) { + for (var i in list) { + if (list[i].name == name) return list[i]; + } + } + + var mbeans = data["solr-mbeans"] + for (var i=0; i=0; + } +} diff --git a/solr/webapp/web/js/angular/services.js b/solr/webapp/web/js/angular/services.js index 3d833c16ff2..18aec1fa492 100644 --- a/solr/webapp/web/js/angular/services.js +++ b/solr/webapp/web/js/angular/services.js @@ -125,7 +125,21 @@ solrAdminServices.factory('System', }]) .factory('Mbeans', ['$resource', function($resource) { - return $resource('/solr/:core/admin/mbeans', {'wt':'json', 'stats': true, '_':Date.now()}); // @core + return $resource('/solr/:core/admin/mbeans', {'wt':'json', core: '@core', '_':Date.now()}, { + stats: {params: {stats: true}}, + reference: { + params: {wt: "xml", stats: true}, transformResponse: function (data) { + return {reference: data} + } + }, + delta: {method: "POST", + params: {stats: true, diff:true}, + headers: {'Content-type': 'application/x-www-form-urlencoded'}, + transformRequest: function(data) { + return "stream.body=" + encodeURIComponent(data); + } + } + }); }]) .factory('Files', ['$resource', function($resource) {