| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- ///<reference path="../../headers/common.d.ts" />
- import angular from 'angular';
- import _ from 'lodash';
- import config from 'app/core/config';
- import coreModule from 'app/core/core_module';
- export class BackendSrv {
- inFlightRequests = {};
- HTTP_REQUEST_CANCELLED = -1;
- /** @ngInject */
- constructor(private $http, private alertSrv, private $rootScope, private $q, private $timeout, private contextSrv) {
- }
- get(url, params?) {
- return this.request({ method: 'GET', url: url, params: params });
- }
- delete(url) {
- return this.request({ method: 'DELETE', url: url });
- }
- post(url, data) {
- return this.request({ method: 'POST', url: url, data: data });
- }
- patch(url, data) {
- return this.request({ method: 'PATCH', url: url, data: data });
- }
- put(url, data) {
- return this.request({ method: 'PUT', url: url, data: data });
- }
- requestErrorHandler(err) {
- if (err.isHandled) {
- return;
- }
- var data = err.data || { message: 'Unexpected error' };
- if (_.isString(data)) {
- data = { message: data };
- }
- if (err.status === 422) {
- this.alertSrv.set("Validation failed", data.message, "warning", 4000);
- throw data;
- }
- data.severity = 'error';
- if (err.status < 500) {
- data.severity = "warning";
- }
- if (data.message) {
- this.alertSrv.set("Problem!", data.message, data.severity, 10000);
- }
- throw data;
- }
- request(options) {
- options.retry = options.retry || 0;
- var requestIsLocal = !options.url.match(/^http/);
- var firstAttempt = options.retry === 0;
- if (requestIsLocal) {
- if (this.contextSrv.user && this.contextSrv.user.orgId) {
- options.headers = options.headers || {};
- options.headers['X-Grafana-Org-Id'] = this.contextSrv.user.orgId;
- }
- if (options.url.indexOf("/") === 0) {
- options.url = options.url.substring(1);
- }
- }
- return this.$http(options).then(results => {
- if (options.method !== 'GET') {
- if (results && results.data.message) {
- if (options.showSuccessAlert !== false) {
- this.alertSrv.set(results.data.message, '', 'success', 3000);
- }
- }
- }
- return results.data;
- }, err => {
- // handle unauthorized
- if (err.status === 401 && firstAttempt) {
- return this.loginPing().then(() => {
- options.retry = 1;
- return this.request(options);
- });
- }
- this.$timeout(this.requestErrorHandler.bind(this, err), 50);
- throw err;
- });
- }
- addCanceler(requestId, canceler) {
- if (requestId in this.inFlightRequests) {
- this.inFlightRequests[requestId].push(canceler);
- } else {
- this.inFlightRequests[requestId] = [canceler];
- }
- }
- resolveCancelerIfExists(requestId) {
- var cancelers = this.inFlightRequests[requestId];
- if (!_.isUndefined(cancelers) && cancelers.length) {
- cancelers[0].resolve();
- }
- }
- datasourceRequest(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 requestId = options.requestId;
- if (requestId) {
- this.resolveCancelerIfExists(requestId);
- // create new canceler
- var canceler = this.$q.defer();
- options.timeout = canceler.promise;
- this.addCanceler(requestId, canceler);
- }
- var requestIsLocal = !options.url.match(/^http/);
- var firstAttempt = options.retry === 0;
- if (requestIsLocal) {
- if (this.contextSrv.user && this.contextSrv.user.orgId) {
- options.headers = options.headers || {};
- options.headers['X-Grafana-Org-Id'] = this.contextSrv.user.orgId;
- }
- if (options.url.indexOf("/") === 0) {
- options.url = options.url.substring(1);
- }
- if (options.headers && options.headers.Authorization) {
- options.headers['X-DS-Authorization'] = options.headers.Authorization;
- delete options.headers.Authorization;
- }
- }
- return this.$http(options).catch(err => {
- if (err.status === this.HTTP_REQUEST_CANCELLED) {
- throw {err, cancelled: true};
- }
- // handle unauthorized for backend requests
- if (requestIsLocal && firstAttempt && err.status === 401) {
- return this.loginPing().then(() => {
- options.retry = 1;
- if (canceler) {
- canceler.resolve();
- }
- return this.datasourceRequest(options);
- });
- }
- //populate error obj on Internal Error
- if (_.isString(err.data) && err.status === 500) {
- err.data = {
- error: err.statusText,
- response: err.data,
- };
- }
- // for Prometheus
- if (!err.data.message && _.isString(err.data.error)) {
- err.data.message = err.data.error;
- }
- throw err;
- }).finally(() => {
- // clean up
- if (options.requestId) {
- this.inFlightRequests[options.requestId].shift();
- }
- });
- }
- loginPing() {
- return this.request({url: '/api/login/ping', method: 'GET', retry: 1 });
- }
- search(query) {
- return this.get('/api/search', query);
- }
- getDashboard(type, slug) {
- return this.get('/api/dashboards/' + type + '/' + slug);
- }
- saveDashboard(dash, options) {
- options = (options || {});
- const message = options.message || '';
- return this.post('/api/dashboards/db/', {dashboard: dash, overwrite: options.overwrite === true, message});
- }
- }
- coreModule.service('backendSrv', BackendSrv);
|