You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by sh...@apache.org on 2017/01/02 13:44:07 UTC
svn commit: r1776930 [3/19] - in /ofbiz/trunk/specialpurpose: lucene/
lucene/src/main/java/org/apache/ofbiz/content/search/ solr/
solr/src/main/java/org/apache/ofbiz/solr/webapp/ solr/webapp/solr/
solr/webapp/solr/WEB-INF/ solr/webapp/solr/css/ solr/we...
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/cores.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/cores.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/cores.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/cores.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,478 @@
+/*
+ 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.
+*/
+
+// @todo test optimize (delete stuff, watch button appear, test button/form)
+solrAdminApp.controller('CoreAdminController',
+ function($scope, $routeParams, $location, $timeout, $route, Cores, Update, Constants){
+ $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]);
+ }
+ }
+ if ($scope.swapCorelist.length>0) {
+ $scope.swapOther = $scope.swapCorelist[0].name;
+ }
+ });
+ };
+ $scope.showAddCore = function() {
+ $scope.hideAll();
+ $scope.showAdd = true;
+ $scope.newCore = {
+ name: "new_core",
+ dataDir: "data",
+ instanceDir: "new_core",
+ config: "solrconfig.xml",
+ schema: "schema.xml",
+ collection: "",
+ shard: ""
+ };
+ };
+
+ $scope.addCore = function() {
+ 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 {
+ var params = {
+ name: $scope.newCore.name,
+ instanceDir: $scope.newCore.instanceDir,
+ config: $scope.newCore.config,
+ schema: $scope.newCore.schema,
+ dataDir: $scope.newCore.dataDir
+ };
+ if ($scope.isCloud) {
+ params.collection = $scope.newCore.collection;
+ params.shard = $scope.newCore.shard;
+ }
+ Cores.add(params, function(data) {
+ $location.path("/~cores/" + $scope.newCore.name);
+ $scope.cancelAddCore();
+ });
+ }
+ };
+
+ $scope.cancelAddCore = function() {
+ delete $scope.addMessage;
+ $scope.showAdd = false
+ };
+
+ $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");
+ });
+ };
+
+ $scope.showRenameCore = function() {
+ $scope.hideAll();
+ $scope.showRename = true;
+ };
+
+ $scope.renameCore = function() {
+ if (!$scope.other) {
+ $scope.renameMessage = "Please provide a new name for the " + $scope.selectedCore + " core";
+ } 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();
+ });
+ }
+ };
+
+ $scope.cancelRenameCore = function() {
+ $scope.showRename = false;
+ delete $scope.renameMessage;
+ $scope.other = "";
+ };
+
+ $scope.showSwapCores = function() {
+ $scope.hideAll();
+ $scope.showSwap = true;
+ };
+
+ $scope.swapCores = function() {
+ if (!$scope.swapOther) {
+ $scope.swapMessage = "Please select a core to swap with";
+ } 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();
+ });
+ }
+ };
+
+ $scope.cancelSwapCores = function() {
+ delete $scope.swapMessage;
+ $scope.showSwap = false;
+ }
+
+ $scope.reloadCore = function() {
+ if ($scope.initFailures[$scope.selectedCore]) {
+ delete $scope.initFailures[$scope.selectedCore];
+ $scope.showInitFailures = Object.keys(data.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);
+ }
+ });
+ };
+
+ $scope.hideAll = function() {
+ $scope.showRename = false;
+ $scope.showAdd = false;
+ $scope.showSwap = false;
+ };
+
+ $scope.optimizeCore = function() {
+ Update.optimize({core: $scope.selectedCore},
+ function(successData) {
+ $scope.optimizeSuccess = true;
+ $timeout(function() {$scope.optimizeSuccess=false}, 1000);
+ $scope.refresh();
+ },
+ function(failureData) {
+ $scope.optimizeFailure = true;
+ $timeout(function () {$scope.optimizeFailure=false}, 1000);
+ $scope.refresh();
+ });
+ };
+
+ $scope.refresh();
+ }
+);
+
+/**************
+ 'cores_load_data',
+ function( event, params )
+ {
+ $.ajax
+ (
+ {
+ url : app.config.solr_path + app.config.core_admin_path + '?wt=json',
+ dataType : 'json',
+ success : function( response, text_status, xhr )
+ {
+ if( params.only_failures )
+ {
+ app.check_for_init_failures( response );
+ return true;
+ }
+
+
+=========== NO CORES
+ error : function()
+ {
+ sammy.trigger
+ (
+ 'cores_load_template',
+ {
+ content_element : content_element,
+ callback : function()
+ {
+ var cores_element = $( '#cores', content_element );
+ var navigation_element = $( '#navigation', cores_element );
+ var data_element = $( '#data', cores_element );
+ var core_data_element = $( '#core-data', data_element );
+ var index_data_element = $( '#index-data', data_element );
+
+ // layout
+
+ var ui_block = $( '#ui-block' );
+ var actions_element = $( '.actions', cores_element );
+ var div_action = $( 'div.action', actions_element );
+
+ ui_block
+ .css( 'opacity', 0.7 )
+ .width( cores_element.width() + 10 )
+ .height( cores_element.height() );
+
+ if( $( '#cloud.global' ).is( ':visible' ) )
+ {
+ $( '.cloud', div_action )
+ .show();
+ }
+
+ $( 'button.action', actions_element )
+ .die( 'click' )
+ .live
+ (
+ 'click',
+ function( event )
+ {
+ var self = $( this );
+
+ self
+ .toggleClass( 'open' );
+
+ $( '.action.' + self.attr( 'id' ), actions_element )
+ .trigger( 'open' );
+
+ return false;
+ }
+ );
+
+ div_action
+ .die( 'close' )
+ .live
+ (
+ 'close',
+ function( event )
+ {
+ div_action.hide();
+ ui_block.hide();
+ }
+ )
+ .die( 'open' )
+ .live
+ (
+ 'open',
+ function( event )
+ {
+ var self = $( this );
+ var rel = $( '#' + self.data( 'rel' ) );
+
+ self
+ .trigger( 'close' )
+ .show()
+ .css( 'left', rel.position().left );
+
+ ui_block
+ .show();
+ }
+ );
+
+ $( 'form button.reset', actions_element )
+ .die( 'click' )
+ .live
+ (
+ 'click',
+ function( event )
+ {
+ $( this ).closest( 'div.action' )
+ .trigger( 'close' );
+ }
+ );
+
+ $( 'form', div_action )
+ .ajaxForm
+ (
+ {
+ url : app.config.solr_path + app.config.core_admin_path + '?wt=json&indexInfo=false',
+ dataType : 'json',
+ beforeSubmit : function( array, form, options )
+ {
+ $( 'button[type="submit"] span', form )
+ .addClass( 'loader' );
+ },
+ success : function( response, status_text, xhr, form )
+ {
+ delete app.cores_data;
+ sammy.refresh();
+
+ $( 'button.reset', form )
+ .trigger( 'click' );
+ },
+ error : function( xhr, text_status, error_thrown )
+ {
+ var response = null;
+ eval( 'response = ' + xhr.responseText + ';' );
+
+ var error_elem = $( '.error', div_action.filter( ':visible' ) );
+ error_elem.show();
+ $( 'span', error_elem ).text( response.error.msg );
+ },
+ complete : function()
+ {
+ $( 'button span.loader', actions_element )
+ .removeClass( 'loader' );
+ }
+ }
+ );
+
+ // --
+
+ $( '#add', content_element )
+ .trigger( 'click' );
+
+ $( '[data-rel="add"] input[type="text"]:first', content_element )
+ .focus();
+ }
+ }
+ );
+ }
+ }
+ );
+ }
+);
+
+// #/~cores
+sammy.get
+(
+ /^#\/(~cores)\//,
+ function( context )
+ {
+ var content_element = $( '#content' );
+
+ var path_parts = this.path.match( /^(.+\/~cores\/)(.*)$/ );
+ var current_core = path_parts[2];
+
+ sammy.trigger
+ (
+ 'cores_load_data',
+ {
+ error : function()
+ {
+ context.redirect( '#/' + context.params.splat[0] );
+ },
+ success : function( cores )
+ {
+ sammy.trigger
+ (
+ 'cores_load_template',
+ {
+ content_element : content_element,
+ callback : function()
+ {
+ var cores_element = $( '#cores', content_element );
+ var navigation_element = $( '#navigation', cores_element );
+ var data_element = $( '#data', cores_element );
+ var core_data_element = $( '#core-data', data_element );
+ var index_data_element = $( '#index-data', data_element );
+
+ cores_element
+ .removeClass( 'empty' );
+
+ var core_data = cores[current_core];
+ var core_basepath = $( '#' + current_core, app.menu_element ).attr( 'data-basepath' );
+
+ var core_names = [];
+ var core_selects = $( '#actions select', cores_element );
+
+ $( 'option[value="' + current_core + '"]', core_selects.filter( '.other' ) )
+ .remove();
+
+ $( 'input[data-core="current"]', cores_element )
+ .val( current_core );
+
+ // layout
+
+ var ui_block = $( '#ui-block' );
+ var actions_element = $( '.actions', cores_element );
+ var div_action = $( 'div.action', actions_element );
+
+ ui_block
+ .css( 'opacity', 0.7 )
+ .width( cores_element.width() + 10 )
+ .height( cores_element.height() );
+
+ if( $( '#cloud.global' ).is( ':visible' ) )
+ {
+ $( '.cloud', div_action )
+ .show();
+ }
+
+ var form_callback = {
+
+ rename : function( form, response )
+ {
+ var url = path_parts[1] + $( 'input[name="other"]', form ).val();
+ context.redirect( url );
+ }
+
+ };
+
+ $( 'form', div_action )
+ .ajaxForm
+ (
+ {
+ url : app.config.solr_path + app.config.core_admin_path + '?wt=json&indexInfo=false',
+ success : function( response, status_text, xhr, form )
+ {
+ var action = $( 'input[name="action"]', form ).val().toLowerCase();
+
+ delete app.cores_data;
+
+ if( form_callback[action] )
+ {
+ form_callback[action]( form, response );
+ }
+ else
+ {
+ sammy.refresh();
+ }
+
+ $( 'button.reset', form )
+ .trigger( 'click' );
+ },
+ );
+
+ $( '#actions #unload', cores_element )
+ var ret = confirm( 'Do you really want to unload Core "' + current_core + '"?' );
+ if( !ret )
+ return false;
+
+ url : app.config.solr_path + app.config.core_admin_path + '?wt=json&action=UNLOAD&core=' + current_core,
+ success : function( response, text_status, xhr )
+ {
+ delete app.cores_data;
+ context.redirect( path_parts[1].substr( 0, path_parts[1].length - 1 ) );
+ },
+
+ optimize_button
+ url : core_basepath + '/update?optimize=true&waitFlush=true&wt=json',
+ success : function( response, text_status, xhr )
+
+******/
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/dataimport.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/dataimport.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/dataimport.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/dataimport.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,303 @@
+/*
+ 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.
+*/
+
+var dataimport_timeout = 2000;
+
+solrAdminApp.controller('DataImportController',
+ function($scope, $rootScope, $routeParams, $location, $timeout, $interval, $cookies, Mbeans, DataImport, Constants) {
+ $scope.resetMenu("dataimport", Constants.IS_COLLECTION_PAGE);
+
+ $scope.refresh = function () {
+ Mbeans.info({core: $routeParams.core, cat: 'QUERYHANDLER'}, function (data) {
+ var mbeans = data['solr-mbeans'][1];
+ $scope.handlers = [];
+ for (var key in mbeans) {
+ if (mbeans[key]['class'] !== key && mbeans[key]['class'] === 'org.apache.solr.handler.dataimport.DataImportHandler') {
+ $scope.handlers.push(key);
+ }
+ }
+ $scope.hasHandlers = $scope.handlers.length > 0;
+
+ if (!$routeParams.handler) {
+ $location.path("/" + $routeParams.core + "/dataimport/" + $scope.handlers[0]);
+ } else {
+ $scope.currentHandler = $routeParams.handler;
+ }
+ });
+
+ $scope.handler = $routeParams.handler;
+ if ($scope.handler && $scope.handler[0]=="/") {
+ $scope.handler = $scope.handler.substr(1);
+ }
+ if ($scope.handler) {
+ DataImport.config({core: $routeParams.core, name: $scope.handler}, function (data) {
+ try {
+ $scope.config = data.config;
+ var xml = $.parseXML(data.config);
+ $scope.entities = [];
+ $('document > entity', xml).each(function (i, element) {
+ $scope.entities.push($(element).attr('name'));
+ });
+ $scope.refreshStatus();
+ } catch (err) {
+ console.log(err);
+ }
+ });
+ }
+ $scope.lastUpdate = "unknown";
+ $scope.lastUpdateUTC = "";
+ };
+
+ $scope.toggleDebug = function () {
+ $scope.isDebugMode = !$scope.isDebugMode;
+ if ($scope.isDebugMode) {
+ // also enable Debug checkbox
+ $scope.form.showDebug = true;
+ }
+ $scope.showConfiguration = true;
+ }
+
+ $scope.toggleConfiguration = function () {
+ $scope.showConfiguration = !$scope.showConfiguration;
+ }
+
+ $scope.toggleRawStatus = function () {
+ $scope.showRawStatus = !$scope.showRawStatus;
+ }
+
+ $scope.toggleRawDebug = function () {
+ $scope.showRawDebug = !$scope.showRawDebug;
+ }
+
+ $scope.reload = function () {
+ DataImport.reload({core: $routeParams.core, name: $scope.handler}, function () {
+ $scope.reloaded = true;
+ $timeout(function () {
+ $scope.reloaded = false;
+ }, 5000);
+ $scope.refresh();
+ });
+ }
+
+ $scope.form = {
+ command: "full-import",
+ verbose: false,
+ clean: true,
+ commit: true,
+ optimize: false,
+ showDebug: false,
+ custom: "",
+ core: $routeParams.core
+ };
+
+ $scope.submit = function () {
+ var params = {};
+ for (var key in $scope.form) {
+ if (key == "showDebug") {
+ if ($scope.form.showDebug) {
+ params["debug"] = true;
+ }
+ } else {
+ params[key] = $scope.form[key];
+ }
+ }
+ if (params.custom.length) {
+ var customParams = $scope.form.custom.split("&");
+ for (var i in customParams) {
+ var parts = customParams[i].split("=");
+ params[parts[0]] = parts[1];
+ }
+ }
+ delete params.custom;
+
+ if ($scope.isDebugMode) {
+ params.dataConfig = $scope.config;
+ }
+
+ params.core = $routeParams.core;
+ params.name = $scope.handler;
+
+ DataImport.post(params, function (data) {
+ $scope.rawResponse = JSON.stringify(data, null, 2);
+ $scope.refreshStatus();
+ });
+ };
+
+ $scope.abort = function () {
+ $scope.isAborting = true;
+ DataImport.abort({core: $routeParams.core, name: $scope.handler}, function () {
+ $timeout(function () {
+ $scope.isAborting = false;
+ $scope.refreshStatus();
+ }, 4000);
+ });
+ }
+
+ $scope.refreshStatus = function () {
+
+ console.log("Refresh Status");
+
+ $scope.isStatusLoading = true;
+ DataImport.status({core: $routeParams.core, name: $scope.handler}, function (data) {
+ if (data[0] == "<") {
+ $scope.hasHandlers = false;
+ return;
+ }
+
+ var now = new Date();
+ $scope.lastUpdate = now.toTimeString().split(' ').shift();
+ $scope.lastUpdateUTC = now.toUTCString();
+ var messages = data.statusMessages;
+ var messagesCount = 0;
+ for( var key in messages ) { messagesCount++; }
+
+ if (data.status == 'busy') {
+ $scope.status = "indexing";
+
+ $scope.timeElapsed = data.statusMessages['Time Elapsed'];
+ $scope.elapsedSeconds = parseSeconds($scope.timeElapsed);
+
+ var info = $scope.timeElapsed ? 'Indexing since ' + $scope.timeElapsed : 'Indexing ...';
+ $scope.info = showInfo(messages, true, info, $scope.elapsedSeconds);
+
+ } else if (messages.RolledBack) {
+ $scope.status = "failure";
+ $scope.info = showInfo(messages, true);
+ } else if (messages.Aborted) {
+ $scope.status = "aborted";
+ $scope.info = showInfo(messages, true, 'Aborting current Import ...');
+ } else if (data.status == "idle" && messagesCount != 0) {
+ $scope.status = "success";
+ $scope.info = showInfo(messages, true);
+ } else {
+ $scope.status = "idle";
+ $scope.info = showInfo(messages, false, 'No information available (idle)');
+ }
+
+ delete data.$promise;
+ delete data.$resolved;
+
+ $scope.rawStatus = JSON.stringify(data, null, 2);
+
+ $scope.isStatusLoading = false;
+ $scope.statusUpdated = true;
+ $timeout(function () {
+ $scope.statusUpdated = false;
+ }, dataimport_timeout / 2);
+ });
+ };
+
+ $scope.updateAutoRefresh = function () {
+ $scope.autorefresh = !$scope.autorefresh;
+ $cookies.dataimport_autorefresh = $scope.autorefresh ? true : null;
+ if ($scope.autorefresh) {
+ $scope.refreshTimeout = $interval($scope.refreshStatus, dataimport_timeout);
+ var onRouteChangeOff = $scope.$on('$routeChangeStart', function() {
+ $interval.cancel($scope.refreshTimeout);
+ onRouteChangeOff();
+ });
+
+ } else if ($scope.refreshTimeout) {
+ $interval.cancel($scope.refreshTimeout);
+ }
+ $scope.refreshStatus();
+ };
+
+ $scope.refresh();
+
+});
+
+var showInfo = function (messages, showFull, info_text, elapsed_seconds) {
+
+ var info = {};
+ if (info_text) {
+ info.text = info_text;
+ } else {
+ info.text = messages[''] || '';
+ // format numbers included in status nicely
+ /* @todo this pretty printing is hard to work out how to do in an Angularesque way:
+ info.text = info.text.replace(/\d{4,}/g,
+ function (match, position, string) {
+ return app.format_number(parseInt(match, 10));
+ }
+ );
+ */
+
+ var time_taken_text = messages['Time taken'];
+ info.timeTaken = parseSeconds(time_taken_text);
+ }
+ info.showDetails = false;
+
+ if (showFull) {
+ if (!elapsed_seconds) {
+ var time_taken_text = messages['Time taken'];
+ elapsed_seconds = parseSeconds(time_taken_text);
+ }
+
+ info.showDetails = true;
+
+ var document_config = {
+ 'Requests': 'Total Requests made to DataSource',
+ 'Fetched': 'Total Rows Fetched',
+ 'Skipped': 'Total Documents Skipped',
+ 'Processed': 'Total Documents Processed'
+ };
+
+ info.docs = [];
+ for (var key in document_config) {
+ var value = parseInt(messages[document_config[key]], 10);
+ var doc = {desc: document_config[key], name: key, value: value};
+ if (elapsed_seconds && key != 'Skipped') {
+ doc.speed = Math.round(value / elapsed_seconds);
+ }
+ info.docs.push(doc);
+ }
+
+ var dates_config = {
+ 'Started': 'Full Dump Started',
+ 'Aborted': 'Aborted',
+ 'Rolledback': 'Rolledback'
+ };
+
+ info.dates = [];
+ for (var key in dates_config) {
+ var value = messages[dates_config[key]];
+ if (value) {
+ value = value.replace(" ", "T")+".000Z";
+ console.log(value);
+ var date = {desc: dates_config[key], name: key, value: value};
+ info.dates.push(date);
+ }
+ }
+ }
+ return info;
+}
+
+var parseSeconds = function(time) {
+ var seconds = 0;
+ var arr = new String(time || '').split('.');
+ var parts = arr[0].split(':').reverse();
+
+ for (var i = 0; i < parts.length; i++) {
+ seconds += ( parseInt(parts[i], 10) || 0 ) * Math.pow(60, i);
+ }
+
+ if (arr[1] && 5 <= parseInt(arr[1][0], 10)) {
+ seconds++; // treat more or equal than .5 as additional second
+ }
+ return seconds;
+}
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/documents.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/documents.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/documents.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/documents.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,139 @@
+/*
+ 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.
+ */
+//helper for formatting JSON and others
+
+var DOC_PLACEHOLDER = '<doc>\n' +
+ '<field name="id">change.me</field>' +
+ '<field name="title">change.me</field>' +
+ '</doc>';
+
+var ADD_PLACEHOLDER = '<add>\n' + DOC_PLACEHOLDER + '</add>\n';
+
+solrAdminApp.controller('DocumentsController',
+ function($scope, $rootScope, $routeParams, $location, Luke, Update, FileUpload, Constants) {
+ $scope.resetMenu("documents", Constants.IS_COLLECTION_PAGE);
+
+ $scope.refresh = function () {
+ Luke.schema({core: $routeParams.core}, function(data) {
+ //TODO: handle dynamic fields
+ delete data.schema.fields._version_;
+ $scope.fields = Object.keys(data.schema.fields);
+ });
+ $scope.document = "";
+ $scope.handler = "/update";
+ $scope.type = "json";
+ $scope.commitWithin = 1000;
+ $scope.overwrite = true;
+ $scope.boost = "1.0";
+ };
+
+ $scope.refresh();
+
+ $scope.changeDocumentType = function () {
+ $scope.placeholder = "";
+ if ($scope.type == 'json') {
+ $scope.placeholder = '{"id":"change.me","title":"change.me"}';
+ } else if ($scope.type == 'csv') {
+ $scope.placeholder = "id,title\nchange.me,change.me";
+ } else if ($scope.type == 'solr') {
+ $scope.placeholder = ADD_PLACEHOLDER;
+ } else if ($scope.type == 'xml') {
+ $scope.placeholder = DOC_PLACEHOLDER;
+ }
+ };
+
+ $scope.addWizardField = function () {
+ if ($scope.document == "") $scope.document = "{}";
+ var doc = JSON.parse($scope.document);
+ doc[$scope.fieldName] = $scope.fieldData;
+ $scope.document = JSON.stringify(doc, null, '\t');
+ $scope.fieldData = "";
+ };
+
+ $scope.submit = function () {
+ var contentType = "";
+ var postData = "";
+ var params = {};
+ var doingFileUpload = false;
+
+ if ($scope.handler[0] == '/') {
+ params.handler = $scope.handler.substring(1);
+ } else {
+ params.handler = 'update';
+ params.qt = $scope.handler;
+ }
+
+ params.commitWithin = $scope.commitWithin;
+ params.boost = $scope.boost;
+ params.overwrite = $scope.overwrite;
+ params.core = $routeParams.core;
+ params.wt = "json";
+
+ if ($scope.type == "json" || $scope.type == "wizard") {
+ postData = "[" + $scope.document + "]";
+ contentType = "json";
+ } else if ($scope.type == "csv") {
+ postData = $scope.document;
+ contentType = "csv";
+ } else if ($scope.type == "xml") {
+ postData = "<add>" + $scope.document + "</add>";
+ contentType = "xml";
+ } else if ($scope.type == "upload") {
+ doingFileUpload = true;
+ params.raw = $scope.literalParams;
+ } else if ($scope.type == "solr") {
+ postData = $scope.document;
+ if (postData[0] == "<") {
+ contentType = "xml";
+ } else if (postData[0] == "{" || postData[0] == '[') {
+ contentType = "json";
+ } else {
+ alert("Cannot identify content type")
+ }
+ }
+ if (!doingFileUpload) {
+ var callback = function (success) {
+ $scope.responseStatus = "success";
+ delete success.$promise;
+ delete success.$resolved;
+ $scope.response = JSON.stringify(success, null, ' ');
+ };
+ var failure = function (failure) {
+ $scope.responseStatus = failure;
+ };
+ if (contentType == "json") {
+ Update.postJson(params, postData, callback, failure);
+ } else if (contentType == "xml") {
+ Update.postXml(params, postData, callback, failure);
+ } else if (contentType == "csv") {
+ Update.postCsv(params, postData, callback, failure);
+ }
+ } else {
+ var file = $scope.fileUpload;
+ console.log('file is ' + JSON.stringify(file));
+ var uploadUrl = "/fileUpload";
+ FileUpload.upload(params, $scope.fileUpload, function (success) {
+ $scope.responseStatus = "success";
+ $scope.response = JSON.stringify(success, null, ' ');
+ }, function (failure) {
+ $scope.responseStatus = "failure";
+ $scope.response = JSON.stringify(failure, null, ' ');
+ });
+ }
+ }
+ });
+
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/files.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/files.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/files.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/files.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,100 @@
+/*
+ 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.
+*/
+
+var contentTypeMap = { xml : 'text/xml', html : 'text/html', js : 'text/javascript', json : 'application/json', 'css' : 'text/css' };
+var languages = {js: "javascript", xml:"xml", xsl:"xml", vm: "xml", html: "xml", json: "json", css: "css"};
+
+solrAdminApp.controller('FilesController',
+ function($scope, $rootScope, $routeParams, $location, Files, Constants) {
+ $scope.resetMenu("files", Constants.IS_COLLECTION_PAGE);
+
+ $scope.file = $location.search().file;
+ $scope.content = null;
+
+ $scope.baseurl = $location.protocol()+ "://" + $location.host() + ":" + $location.port();
+
+ $scope.refresh = function () {
+
+ var process = function (path, tree) {
+ var params = {core: $routeParams.core};
+ if (path.slice(-1) == '/') {
+ params.file = path.slice(0, -1);
+ } else if (path!='') {
+ params.file = path;
+ }
+
+ Files.list(params, function (data) {
+ var filenames = Object.keys(data.files);
+ filenames.sort();
+ for (var i in filenames) {
+ var file = filenames[i];
+ var filedata = data.files[file];
+ var state = undefined;
+ var children = undefined;
+
+ if (filedata.directory) {
+ file = file + "/";
+ if ($scope.file && $scope.file.indexOf(path + file) == 0) {
+ state = "open";
+ } else {
+ state = "closed";
+ }
+ children = [];
+ process(path + file, children);
+ }
+ tree.push({
+ data: {
+ title: file,
+ attr: { id: path + file}
+ },
+ children: children,
+ state: state
+ });
+ }
+ });
+ }
+ $scope.tree = [];
+ process("", $scope.tree);
+
+ if ($scope.file && $scope.file != '' && $scope.file.split('').pop()!='/') {
+ var extension;
+ if ($scope.file == "managed-schema") {
+ extension = contentTypeMap['xml'];
+ } else {
+ extension = $scope.file.match( /\.(\w+)$/)[1] || '';
+ }
+ var contentType = (contentTypeMap[extension] || 'text/plain' ) + ';charset=utf-8';
+
+ Files.get({core: $routeParams.core, file: $scope.file, contentType: contentType}, function(data) {
+ $scope.content = data.data;
+ $scope.url = $scope.baseurl + data.config.url + "?" + $.param(data.config.params);
+ if (contentType.indexOf("text/plain") && (data.data.indexOf("<?xml")>=0) || data.data.indexOf("<!--")>=0) {
+ $scope.lang = "xml";
+ } else {
+ $scope.lang = languages[extension] || "txt";
+ }
+ });
+ }
+ };
+
+ $scope.showTreeLink = function(data) {
+ var file = data.args[0].id;
+ $location.search({file:file});
+ };
+
+ $scope.refresh();
+ });
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/index.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/index.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/index.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/index.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,97 @@
+/*
+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('IndexController', function($scope, System, Cores, Constants) {
+ $scope.resetMenu("index", Constants.IS_ROOT_PAGE);
+ $scope.reload = function() {
+ System.get(function(data) {
+ $scope.system = data;
+
+ // load average
+ var load_average = ( data.system.uptime || '' ).match( /load averages?: (\d+[.,]\d\d),? (\d+[.,]\d\d),? (\d+[.,]\d\d)/ );
+ if (load_average) {
+ for (var i=0;i<2;i++) {
+ load_average[i]=load_average[i].replace(",","."); // for European users
+ }
+ $scope.load_average = load_average.slice(1);
+ }
+
+ // 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);
+
+ // no info bar:
+ $scope.noInfo = !(
+ data.system.totalPhysicalMemorySize && data.system.freePhysicalMemorySize &&
+ data.system.totalSwapSpaceSize && data.system.freeSwapSpaceSize &&
+ data.system.openFileDescriptorCount && data.system.maxFileDescriptorCount);
+
+ // command line args:
+ $scope.commandLineArgs = data.jvm.jmx.commandLineArgs.sort();
+ });
+ };
+ $scope.reload();
+});
+
+var parse_memory_value = function( value ) {
+ if( value !== Number( value ) )
+ {
+ var units = 'BKMGTPEZY';
+ var match = value.match( /^(\d+([,\.]\d+)?) (\w).*$/ );
+ var value = parseFloat( match[1] ) * Math.pow( 1024, units.indexOf( match[3].toUpperCase() ) );
+ }
+
+ return value;
+};
+
+var pretty_print_bytes = function(byte_value) {
+ var unit = null;
+
+ byte_value /= 1024;
+ byte_value /= 1024;
+ unit = 'MB';
+
+ if( 1024 <= byte_value ) {
+ byte_value /= 1024;
+ unit = 'GB';
+ }
+ return byte_value.toFixed( 2 ) + ' ' + unit;
+};
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/java-properties.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/java-properties.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/java-properties.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/java-properties.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,45 @@
+/*
+ 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('JavaPropertiesController',
+ function($scope, Properties, Constants){
+ $scope.resetMenu("java-props", Constants.IS_ROOT_PAGE);
+ $scope.refresh = function() {
+ Properties.get(function(data) {
+ var sysprops = data["system.properties"];
+ var sep = sysprops["path.separator"]
+ var props = [];
+ for (var key in sysprops) {
+ var value = sysprops[key];
+ var key = key.replace(/\./g, '.​');
+ if (key.indexOf(".path")!=-1 || key.indexOf(".dirs")) {
+ var values = [];
+ var parts = value.split(sep);
+ for (var i in parts) {
+ values.push({pos:i, value:parts[i]})
+ }
+ props.push({name: key, values: values});
+ } else {
+ props.push({name: key, values: [value]});
+ }
+ }
+ $scope.props = props;
+ });
+ };
+
+ $scope.refresh();
+ });
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/logging.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/logging.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/logging.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/logging.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,150 @@
+/*
+ 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.
+*/
+
+var format_time_content = function( time, timeZone ) {
+ var format_time_options = {};
+ if (timeZone && timeZone!="Local") {
+ format_time_options.timeZone = timeZone;
+ }
+ return time.toLocaleString( undefined, format_time_options );
+}
+
+solrAdminApp.controller('LoggingController',
+ function($scope, $timeout, $cookies, Logging, Constants){
+ $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();
+
+ 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;
+ }
+ $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
+ );
+ }
+ */
+ });
+ $scope.timeout = $timeout($scope.refresh, 10000);
+ var onRouteChangeOff = $scope.$on('$routeChangeStart', function() {
+ $timeout.cancel($scope.timeout);
+ onRouteChangeOff();
+ });
+ };
+ $scope.refresh();
+
+ $scope.toggleTimezone = function() {
+ $scope.timezone = ($scope.timezone=="Local") ? "UTC":"Local";
+ $cookies.logging_timezone = $scope.timezone;
+ }
+ $scope.toggleRow = function(event) {
+ event.showTrace =! event.showTrace;
+ };
+ }
+)
+
+.controller('LoggingLevelController',
+ function($scope, Logging) {
+ $scope.resetMenu("logging-levels");
+
+ var packageOf = function(logger) {
+ var parts = logger.name.split(".");
+ return !parts.pop() ? "" : parts.join(".");
+ };
+
+ var shortNameOf = function(logger) {return logger.name.split(".").pop();}
+
+ var makeTree = function(loggers, packag) {
+ var tree = [];
+ for (var i=0; i<loggers.length; i++) {
+ var logger = loggers[i];
+ logger.packag = packageOf(logger);
+ logger.short = shortNameOf(logger);
+ if (logger.packag == packag) {
+ logger.children = makeTree(loggers, logger.name);
+ tree.push(logger);
+ }
+ }
+ return tree;
+ };
+
+ $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});
+ }
+ });
+ };
+
+ $scope.toggleOptions = function(logger) {
+ if (logger.showOptions) {
+ logger.showOptions = false;
+ delete $scope.currentLogger;
+ } else {
+ if ($scope.currentLogger) {
+ $scope.currentLogger.showOptions = false;
+ }
+ logger.showOptions = true;
+ $scope.currentLogger = logger;
+ }
+ };
+
+ $scope.setLevel = function(logger, newLevel) {
+ var setString = logger.name + ":" + newLevel;
+ logger.showOptions = false;
+ Logging.setLevel({set: setString}, function(data) {
+ $scope.refresh();
+ });
+ };
+
+ $scope.refresh();
+ });
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/plugins.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/plugins.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/plugins.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/plugins.js Mon Jan 2 13:44:06 2017
@@ -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, Constants) {
+ $scope.resetMenu("plugins", Constants.IS_CORE_PAGE);
+
+ 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<mbeans.length; i+=2) {
+ var key = mbeans[i];
+ var lower = key.toLowerCase();
+ var plugins = getPlugins(mbeans[i+1]);
+ keys.push({name: key,
+ selected: lower == selected,
+ changes: 0,
+ lower: lower,
+ plugins: plugins
+ });
+ }
+ keys.sort(function(a,b) {return a.name > 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<mbeans.length; i+=2) {
+ var typeName = mbeans[i];
+ var type = getByName(types, typeName);
+ var plugins = mbeans[i+1];
+ for (var key in plugins) {
+ var changedPlugin = plugins[key];
+ if (changedPlugin._changed_) {
+ var plugin = getByName(type.plugins, key);
+ var stats = changedPlugin.stats;
+ delete changedPlugin.stats;
+ plugin.properties = changedPlugin;
+ for (var stat in stats) {
+ // add breaking space after a bracket or @ to handle wrap long lines:
+ plugin.stats[stat] = new String(stats[stat]).replace( /([\(@])/g, '$1​');
+ }
+ plugin.changed = true;
+ type.changes++;
+ }
+ }
+ }
+};
+
+var openPlugins = function(type, selected) {
+ for (var i in type.plugins) {
+ var plugin = type.plugins[i];
+ plugin.open = selected.indexOf(plugin.name)>=0;
+ }
+}
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/query.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/query.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/query.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/query.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,114 @@
+/*
+ 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('QueryController',
+ function($scope, $routeParams, $location, Query, Constants){
+ $scope.resetMenu("query", Constants.IS_COLLECTION_PAGE);
+
+ // @todo read URL parameters into scope
+ $scope.query = {wt: 'json', q:'*:*', indent:'on'};
+ $scope.filters = [{fq:""}];
+ $scope.dismax = {defType: "dismax"};
+ $scope.edismax = {defType: "edismax", stopwords: true, lowercaseOperators: true};
+ $scope.hl = {hl:"on"};
+ $scope.facet = {facet: "on"};
+ $scope.spatial = {};
+ $scope.spellcheck = {spellcheck:"on"};
+ $scope.qt = "/select";
+
+ $scope.doQuery = function() {
+ var params = {};
+
+ var set = function(key, value) {
+ if (params[key]) {
+ params[key].push(value);
+ } else {
+ params[key] = [value];
+ }
+ }
+ var copy = function(params, query) {
+ for (var key in query) {
+ terms = query[key];
+ if (terms.length > 0 && key[0]!="$") {
+ set(key, terms);
+ }
+ }
+ };
+
+ copy(params, $scope.query);
+
+ if ($scope.isDismax) copy(params, $scope.dismax);
+ if ($scope.isEdismax) copy(params, $scope.edismax);
+ if ($scope.isHighlight) copy(params, $scope.hl);
+ if ($scope.isFacet) copy(params, $scope.facet);
+ if ($scope.isSpatial) copy(params, $scope.spatial);
+ if ($scope.isSpellcheck) copy(params, $scope.spellcheck);
+
+ if ($scope.rawParams) {
+ var rawParams = $scope.rawParams.split(/[&\n]/);
+ for (var i in rawParams) {
+ var param = rawParams[i];
+ var equalPos = param.indexOf("=");
+ if (equalPos > -1) {
+ set(param.substring(0, equalPos), param.substring(equalPos+1));
+ } else {
+ set(param, ""); // Use empty value for params without "="
+ }
+ }
+ }
+
+ var qt = $scope.qt ? $scope.qt : "/select";
+
+ for (var filter in $scope.filters) {
+ copy(params, $scope.filters[filter]);
+ }
+
+ params.core = $routeParams.core;
+ if (qt[0] == '/') {
+ params.handler = qt.substring(1);
+ } else { // Support legacy style handleSelect=true configs
+ params.handler = "select";
+ set("qt", qt);
+ }
+ var url = Query.url(params);
+ Query.query(params, function(data) {
+ $scope.lang = $scope.query.wt;
+ $scope.response = data;
+ $scope.url = $location.protocol() + "://" +
+ $location.host() + ":" +
+ $location.port() + url;
+ });
+ };
+
+ if ($location.search().q) {
+ $scope.query.q = $location.search()["q"];
+ $scope.doQuery();
+ }
+
+ $scope.removeFilter = function(index) {
+ if ($scope.filters.length === 1) {
+ $scope.filters = [{fq: ""}];
+ } else {
+ $scope.filters.splice(index, 1);
+ }
+ };
+
+ $scope.addFilter = function(index) {
+ $scope.filters.splice(index+1, 0, {fq:""});
+ };
+ }
+);
Added: ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/replication.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/replication.js?rev=1776930&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/replication.js (added)
+++ ofbiz/trunk/specialpurpose/solr/webapp/solr/js/angular/controllers/replication.js Mon Jan 2 13:44:06 2017
@@ -0,0 +1,235 @@
+/*
+ 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('ReplicationController',
+ function($scope, $rootScope, $routeParams, $interval, $timeout, Replication, Constants) {
+ $scope.resetMenu("replication", Constants.IS_CORE_PAGE);
+
+ $scope.iterationCount = 1;
+
+ $scope.refresh = function() {
+ Replication.details({core:$routeParams.core}, function(response) {
+ var timeout;
+ var interval;
+ if ($scope.interval) $interval.cancel($scope.interval);
+ $scope.isSlave = (response.details.isSlave === 'true');
+ if ($scope.isSlave) {
+ $scope.progress = getProgressDetails(response.details.slave);
+ $scope.iterations = getIterations(response.details.slave);
+ $scope.versions = getSlaveVersions(response.details);
+ $scope.settings = getSlaveSettings(response.details);
+ if ($scope.settings.isReplicating) {
+ timeout = $timeout($scope.refresh, 1000);
+ } else if(!$scope.settings.isPollingDisabled && $scope.settings.pollInterval) {
+ interval = $scope.interval = $interval(function() {
+ $scope.settings.tick--;
+ }, 1000, $scope.settings.tick);
+ timeout = $timeout($scope.refresh, 1000*(1+$scope.settings.tick));
+ }
+ } else {
+ $scope.versions = getMasterVersions(response.details);
+ }
+ $scope.master = getMasterSettings(response.details, $scope.isSlave);
+
+ var onRouteChangeOff = $scope.$on('$routeChangeStart', function() {
+ if (interval) $interval.cancel(interval);
+ if (timeout) $timeout.cancel(timeout);
+ onRouteChangeOff();
+ });
+ });
+
+ };
+
+ $scope.execute = function(command) {
+ Replication.command({core:$routeParams.core, command:command}, function(data){$scope.refresh()});
+ }
+
+ $scope.showIterations = function() { $scope.iterationCount = 100000}; // limitTo should accept undefined, but doesn't work.
+ $scope.hideIterations = function() { $scope.iterationCount = 1};
+
+ $scope.refresh();
+ });
+
+var getProgressDetails = function(progress) {
+
+ progress.timeRemaining = parseSeconds(progress.timeRemaining);
+ progress.totalPercent = parseInt(progress.totalPercent);
+ if (progress.totalPercent === 0) {
+ progress.totalPercentWidth = "1px";
+ } else {
+ progress.totalPercentWidth = progress.totalPercent + "%";
+ }
+ progress.currentFileSizePercent = parseInt(progress.currentFileSizePercent);
+
+ if (!progress.indexReplicatedAtList) {
+ progress.indexReplicatedAtList = [];
+ }
+
+ if (!progress.replicationFailedAtList) {
+ progress.replicationFailedAtList = [];
+ }
+ return progress;
+};
+
+var getIterations = function(slave) {
+
+ var iterations = [];
+
+ var find = function(list, date) {
+ return list.filter(function(e) {return e.date == date});
+ };
+
+ for (var i in slave.indexReplicatedAtList) {
+ var date = slave.indexReplicatedAtList[i];
+ var iteration = {date:date, status:"replicated", latest: false};
+ if (date == slave.indexReplicatedAt) {
+ iteration.latest = true;
+ }
+ iterations.push(iteration);
+ }
+
+ for (var i in slave.replicationFailedAtList) {
+ var failedDate = slave.replicationFailedAtList[i];
+ var matchingIterations = find(iterations, failedDate);
+ if (matchingIterations) {
+ iteration = matchingIterations[0];
+ } else {
+ iteration = {date: failedDate, latest:false};
+ iterations.push(iteration);
+ }
+ iteration.status = "failed";
+ if (failedDate == slave.replicationFailedAt) {
+ iteration.latest = true;
+ }
+ }
+ iterations.sort(function(a,b){ return a.date> b.date;}).reverse();
+ return iterations;
+};
+
+var getMasterVersions = function(data) {
+ versions = {masterSearch:{}, master:{}};
+
+ versions.masterSearch.version = data.indexVersion;
+ versions.masterSearch.generation = data.generation;
+ versions.masterSearch.size = data.indexSize;
+
+ versions.master.version = data.master.replicableVersion || '-';
+ versions.master.generation = data.master.replicableGeneration || '-';
+ versions.master.size = '-';
+
+ return versions;
+};
+
+var getSlaveVersions = function(data) {
+ versions = {masterSearch: {}, master: {}, slave: {}};
+
+ versions.slave.version = data.indexVersion;
+ versions.slave.generation = data.generation;
+ versions.slave.size = data.indexSize;
+
+ versions.master.version = data.slave.masterDetails.replicableVersion || '-';
+ versions.master.generation = data.slave.masterDetails.replicableGeneration || '-';
+ versions.master.size = '-';
+
+ versions.masterSearch.version = data.slave.masterDetails.indexVersion;
+ versions.masterSearch.generation = data.slave.masterDetails.generation;
+ versions.masterSearch.size = data.slave.masterDetails.indexSize;
+
+ versions.changedVersion = data.indexVersion !== data.slave.masterDetails.indexVersion;
+ versions.changedGeneration = data.generation !== data.slave.masterDetails.generation;
+
+ return versions;
+};
+
+var parseDateToEpoch = function(date) {
+ // ["Sat Mar 03 11:00:00 CET 2012", "Sat", "Mar", "03", "11:00:00", "CET", "2012"]
+ var parts = date.match( /^(\w+)\s+(\w+)\s+(\d+)\s+(\d+\:\d+\:\d+)\s+(\w+)\s+(\d+)$/ );
+
+ // "Sat Mar 03 2012 10:37:33"
+ var d = new Date( parts[1] + ' ' + parts[2] + ' ' + parts[3] + ' ' + parts[6] + ' ' + parts[4] );
+ return d.getTime();
+}
+
+var parseSeconds = function(time) {
+ var seconds = 0;
+ var arr = new String(time || '').split('.');
+ var parts = arr[0].split(':').reverse();
+
+ for (var i = 0; i < parts.length; i++) {
+ seconds += ( parseInt(parts[i], 10) || 0 ) * Math.pow(60, i);
+ }
+
+ if (arr[1] && 5 <= parseInt(arr[1][0], 10)) {
+ seconds++; // treat more or equal than .5 as additional second
+
+ }
+
+ return seconds;
+}
+
+var getSlaveSettings = function(data) {
+ var settings = {};
+ settings.masterUrl = data.slave.masterUrl;
+ settings.isPollingDisabled = data.slave.isPollingDisabled == 'true';
+ settings.pollInterval = data.slave.pollInterval;
+ settings.isReplicating = data.slave.isReplicating == 'true';
+ settings.nextExecutionAt = data.slave.nextExecutionAt;
+
+ if(settings.isReplicating) {
+ settings.isApprox = true;
+ settings.tick = parseSeconds(settings.pollInterval);
+ } else if (!settings.isPollingDisabled && settings.pollInterval) {
+ if( settings.nextExecutionAt ) {
+ settings.nextExecutionAtEpoch = parseDateToEpoch(settings.nextExecutionAt);
+ settings.currentTime = parseDateToEpoch(data.slave.currentDate);
+
+ if( settings.nextExecutionAtEpoch > settings.currentTime) {
+ settings.isApprox = false;
+ settings.tick = ( settings.nextExecutionAtEpoch - settings.currentTime) / 1000;
+ }
+ }
+ }
+ return settings;
+};
+
+var getMasterSettings = function(details, isSlave) {
+ var master = {};
+ var masterData = isSlave ? details.slave.masterDetails.master : details.master;
+ master.replicationEnabled = masterData.replicationEnabled == "true";
+ master.replicateAfter = masterData.replicateAfter.join(", ");
+
+ if (masterData.confFiles) {
+ master.files = [];
+ var confFiles = masterData.confFiles.split(',');
+ for (var i=0; i<confFiles.length; i++) {
+ var file = confFiles[i];
+ var short = file;
+ var title = file;
+ if (file.indexOf(":")>=0) {
+ title = file.replace(':', ' ยป ');
+ var parts = file.split(':');
+ if (isSlave) {
+ short = parts[1];
+ } else {
+ short = parts[0];
+ }
+ }
+ master.files.push({title:title, name:short});
+ }
+ }
+ return master;
+}