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; +} |
Free forum by Nabble | Edit this page |