Files
grafana/public/app/core/services/backend_srv.js

176 lines
5.0 KiB
JavaScript
Raw Normal View History

2014-09-21 15:02:06 +02:00
define([
'angular',
'lodash',
'../core_module',
2015-10-30 14:19:02 +01:00
'app/core/config',
2014-09-21 15:02:06 +02:00
],
function (angular, _, coreModule, config) {
2014-09-21 15:02:06 +02:00
'use strict';
coreModule.default.service('backendSrv', function($http, alertSrv, $timeout, $q) {
var self = this;
2014-09-21 15:02:06 +02:00
this.get = function(url, params) {
return this.request({ method: 'GET', url: url, params: params });
2014-09-21 15:02:06 +02:00
};
2014-12-17 17:31:57 +01:00
this.delete = function(url) {
return this.request({ method: 'DELETE', url: url });
};
2014-12-16 16:44:45 +01:00
this.post = function(url, data) {
return this.request({ method: 'POST', url: url, data: data });
};
this.patch = function(url, data) {
return this.request({ method: 'PATCH', url: url, data: data });
};
2014-12-19 12:52:00 +01:00
this.put = function(url, data) {
return this.request({ method: 'PUT', url: url, data: data });
};
this._handleError = function(err) {
return function() {
if (err.isHandled) {
return;
}
var data = err.data || { message: 'Unexpected error' };
if (_.isString(data)) {
data = { message: data };
}
if (err.status === 422) {
alertSrv.set("Validation failed", data.message, "warning", 4000);
throw data;
}
data.severity = 'error';
if (err.status < 500) {
data.severity = "warning";
}
if (data.message) {
alertSrv.set("Problem!", data.message, data.severity, 10000);
}
throw data;
};
};
2014-09-21 15:02:06 +02:00
this.request = function(options) {
options.retry = options.retry || 0;
var requestIsLocal = options.url.indexOf('/') === 0;
var firstAttempt = options.retry === 0;
2014-09-21 15:02:06 +02:00
if (requestIsLocal && !options.hasSubUrl) {
options.url = config.appSubUrl + options.url;
options.hasSubUrl = true;
2015-03-27 06:47:58 +01:00
}
return $http(options).then(function(results) {
2014-09-21 15:02:06 +02:00
if (options.method !== 'GET') {
if (results && results.data.message) {
alertSrv.set(results.data.message, '', 'success', 3000);
}
2014-09-21 15:02:06 +02:00
}
return results.data;
}, function(err) {
// handle unauthorized
if (err.status === 401 && firstAttempt) {
return self.loginPing().then(function() {
options.retry = 1;
return self.request(options);
});
}
$timeout(self._handleError(err), 50);
throw err;
});
};
var datasourceInFlightRequests = {};
var HTTP_REQUEST_ABORTED = -1;
this.datasourceRequest = function(options) {
options.retry = options.retry || 0;
// A requestID is provided by the datasource as a unique identifier for a
// particular query. If the requestID exists, the promise it is keyed to
// is canceled, canceling the previous datasource request if it is still
// in-flight.
var canceler;
if (options.requestID) {
if (canceler = datasourceInFlightRequests[options.requestID]) {
canceler.resolve();
}
canceler = $q.defer();
options.timeout = canceler.promise;
datasourceInFlightRequests[options.requestID] = canceler;
}
var requestIsLocal = options.url.indexOf('/') === 0;
var firstAttempt = options.retry === 0;
if (requestIsLocal && options.headers && options.headers.Authorization) {
options.headers['X-DS-Authorization'] = options.headers.Authorization;
delete options.headers.Authorization;
}
return $http(options).then(null, function(err) {
if (err.status === HTTP_REQUEST_ABORTED) {
// TODO: Hitting refresh before the original request returns cancels
// the "loading" animation on the panes, but it should continue to be
// visible.
err.statusText = "request aborted";
return err;
}
// handle unauthorized for backend requests
if (requestIsLocal && firstAttempt && err.status === 401) {
return self.loginPing().then(function() {
options.retry = 1;
2016-06-09 15:16:53 +02:00
if (canceler) {
canceler.resolve();
}
return self.datasourceRequest(options);
});
}
//populate error obj on Internal Error
2016-03-21 12:43:30 +01:00
if (_.isString(err.data) && err.status === 500) {
err.data = {
error: err.statusText
};
}
// for Prometheus
if (!err.data.message && _.isString(err.data.error)) {
err.data.message = err.data.error;
}
throw err;
2014-09-21 15:02:06 +02:00
});
};
this.loginPing = function() {
return this.request({url: '/api/login/ping', method: 'GET', retry: 1 });
};
this.search = function(query) {
return this.get('/api/search', query);
};
this.getDashboard = function(type, slug) {
return this.get('/api/dashboards/' + type + '/' + slug);
};
this.saveDashboard = function(dash, options) {
options = (options || {});
return this.post('/api/dashboards/db/', {dashboard: dash, overwrite: options.overwrite === true});
};
2014-09-21 15:02:06 +02:00
});
});