/* | |
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; | |
} |