query_ctrl.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import _ from 'lodash';
  2. import { QueryCtrl } from 'app/plugins/sdk';
  3. import appEvents from 'app/core/app_events';
  4. export interface QueryMeta {
  5. rawQuery: string;
  6. rawQueryString: string;
  7. }
  8. export class StackdriverQueryCtrl extends QueryCtrl {
  9. static templateUrl = 'partials/query.editor.html';
  10. target: {
  11. project: {
  12. id: string;
  13. name: string;
  14. };
  15. metricType: string;
  16. refId: string;
  17. };
  18. defaultDropdownValue = 'Select metric';
  19. defaults = {
  20. project: {
  21. id: 'default',
  22. name: 'loading project...',
  23. },
  24. // metricType: this.defaultDropdownValue,
  25. };
  26. showHelp: boolean;
  27. showLastQuery: boolean;
  28. lastQueryMeta: QueryMeta;
  29. lastQueryError?: string;
  30. /** @ngInject */
  31. constructor($scope, $injector) {
  32. super($scope, $injector);
  33. _.defaultsDeep(this.target, this.defaults);
  34. this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
  35. this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
  36. this.getCurrentProject().then(this.getMetricTypes.bind(this));
  37. }
  38. async getCurrentProject() {
  39. try {
  40. const projects = await this.datasource.getProjects();
  41. if (projects && projects.length > 0) {
  42. this.target.project = projects[0];
  43. } else {
  44. throw new Error('No projects found');
  45. }
  46. } catch (error) {
  47. let message = 'Projects cannot be fetched: ';
  48. message += error.statusText ? error.statusText + ': ' : '';
  49. if (error && error.data && error.data.error && error.data.error.message) {
  50. if (error.data.error.code === 403) {
  51. message += `
  52. A list of projects could not be fetched from the Google Cloud Resource Manager API.
  53. You might need to enable it first:
  54. https://console.developers.google.com/apis/library/cloudresourcemanager.googleapis.com`;
  55. } else {
  56. message += error.data.error.code + '. ' + error.data.error.message;
  57. }
  58. } else {
  59. message += 'Cannot connect to Stackdriver API';
  60. }
  61. appEvents.emit('ds-request-error', message);
  62. }
  63. }
  64. async getMetricTypes() {
  65. //projects/raintank-production/metricDescriptors/agent.googleapis.com/agent/api_request_count
  66. if (this.target.project.id !== 'default') {
  67. const metricTypes = await this.datasource.getMetricTypes(this.target.project.id);
  68. if (this.target.metricType === this.defaultDropdownValue && metricTypes.length > 0) {
  69. this.$scope.$apply(() => (this.target.metricType = metricTypes[0].name));
  70. }
  71. return metricTypes.map(mt => ({ value: mt.id, text: mt.id }));
  72. } else {
  73. return [];
  74. }
  75. }
  76. onDataReceived(dataList) {
  77. this.lastQueryError = null;
  78. this.lastQueryMeta = null;
  79. const anySeriesFromQuery: any = _.find(dataList, { refId: this.target.refId });
  80. if (anySeriesFromQuery) {
  81. this.lastQueryMeta = anySeriesFromQuery.meta;
  82. this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery);
  83. }
  84. }
  85. onDataError(err) {
  86. if (err.data && err.data.results) {
  87. const queryRes = err.data.results[this.target.refId];
  88. if (queryRes) {
  89. this.lastQueryMeta = queryRes.meta;
  90. this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery);
  91. let jsonBody;
  92. try {
  93. jsonBody = JSON.parse(queryRes.error);
  94. } catch {
  95. this.lastQueryError = queryRes.error;
  96. }
  97. this.lastQueryError = jsonBody.error.message;
  98. }
  99. }
  100. }
  101. }