From dea6369d3818605ab719c7d2c603a09a425ceb7b Mon Sep 17 00:00:00 2001 From: MGJamJam Date: Tue, 2 Apr 2024 15:34:53 -0300 Subject: [PATCH 1/4] implements the testDatasource method --- .../src/datasource.ts | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/bitmovin-analytics-datasource/src/datasource.ts b/bitmovin-analytics-datasource/src/datasource.ts index fc0c7c7..8f1a920 100644 --- a/bitmovin-analytics-datasource/src/datasource.ts +++ b/bitmovin-analytics-datasource/src/datasource.ts @@ -6,10 +6,13 @@ import { MutableDataFrame, FieldType, } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; +import { lastValueFrom } from 'rxjs'; import { MyQuery, MyDataSourceOptions } from './types'; export class DataSource extends DataSourceApi { + baseUrl: string; apiKey: string; tenantOrgId?: string; adAnalytics?: boolean; @@ -20,6 +23,7 @@ export class DataSource extends DataSourceApi { this.apiKey = instanceSettings.jsonData.apiKey; this.tenantOrgId = instanceSettings.jsonData.tenantOrgId; this.adAnalytics = instanceSettings.jsonData.adAnalytics; + this.baseUrl = instanceSettings.url!; } async query(options: DataQueryRequest): Promise { @@ -41,11 +45,32 @@ export class DataSource extends DataSourceApi { return { data }; } - async testDatasource() { - // Implement a health check for your data source. - return { - status: 'success', - message: 'Success', + async request(url: string, method: string) { + const options = { + url: this.baseUrl + url, + headers: { 'X-Api-Key': this.apiKey }, + method: method, }; + const response = getBackendSrv().fetch(options); + + return lastValueFrom(response); + } + + async testDatasource() { + const response = await this.request('/analytics/licenses', 'GET'); + + if (response.status === 200) { + return { + status: 'success', + message: 'Datasource setup successfully.', + }; + } else { + return { + status: 'error', + message: response.statusText + ? response.statusText + : 'An unexpected error occurred. Datasource not setup correctly.', + }; + } } } From b04010d8a788671038c4604c056af596ee6fea32 Mon Sep 17 00:00:00 2001 From: MGJamJam Date: Wed, 3 Apr 2024 16:30:21 -0300 Subject: [PATCH 2/4] add useEffect to automatically set the url --- .../src/components/ConfigEditor.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx b/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx index f91efee..e570c5e 100644 --- a/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx +++ b/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx @@ -1,4 +1,4 @@ -import React, { ChangeEvent } from 'react'; +import React, { ChangeEvent, useEffect } from 'react'; import { DataSourceHttpSettings, FieldSet, InlineField, InlineSwitch, Input } from '@grafana/ui'; import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { MyDataSourceOptions } from '../types'; @@ -8,6 +8,12 @@ interface Props extends DataSourcePluginOptionsEditorProps export function ConfigEditor(props: Props) { const { onOptionsChange, options } = props; + useEffect(() => { + if (options.url === '' || options.url == null) { + onOptionsChange({ ...options, url: 'https://api.bitmovin.com/v1' }); + } + }, []); + const onAdAnalyticsChange = (event: ChangeEvent) => { const jsonData = { ...options.jsonData, From e8a55bc097006e329492e11fafca30707bb5a29b Mon Sep 17 00:00:00 2001 From: MGJamJam Date: Thu, 4 Apr 2024 11:49:05 -0300 Subject: [PATCH 3/4] adds comment for useEffect --- bitmovin-analytics-datasource/src/components/ConfigEditor.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx b/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx index e570c5e..60c8455 100644 --- a/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx +++ b/bitmovin-analytics-datasource/src/components/ConfigEditor.tsx @@ -8,10 +8,12 @@ interface Props extends DataSourcePluginOptionsEditorProps export function ConfigEditor(props: Props) { const { onOptionsChange, options } = props; + // sets the instanceSettings.url to the default bitmovin api url if it is not already set when opening the ConfigEditor useEffect(() => { if (options.url === '' || options.url == null) { onOptionsChange({ ...options, url: 'https://api.bitmovin.com/v1' }); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const onAdAnalyticsChange = (event: ChangeEvent) => { From 5cf7556ff91a3cb30216d8bae07864e3ea211b12 Mon Sep 17 00:00:00 2001 From: MGJamJam Date: Thu, 4 Apr 2024 11:51:06 -0300 Subject: [PATCH 4/4] improves ErrorMessage --- .../src/datasource.ts | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/bitmovin-analytics-datasource/src/datasource.ts b/bitmovin-analytics-datasource/src/datasource.ts index 8f1a920..08d2d86 100644 --- a/bitmovin-analytics-datasource/src/datasource.ts +++ b/bitmovin-analytics-datasource/src/datasource.ts @@ -7,7 +7,7 @@ import { FieldType, } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { lastValueFrom } from 'rxjs'; +import { catchError, lastValueFrom, map, of, Observable } from 'rxjs'; import { MyQuery, MyDataSourceOptions } from './types'; @@ -51,26 +51,43 @@ export class DataSource extends DataSourceApi { headers: { 'X-Api-Key': this.apiKey }, method: method, }; - const response = getBackendSrv().fetch(options); - - return lastValueFrom(response); + return getBackendSrv().fetch(options); } async testDatasource() { - const response = await this.request('/analytics/licenses', 'GET'); + return lastValueFrom( + this.request('/analytics/licenses', 'GET').pipe( + map(() => { + return { + status: 'success', + message: 'Data source successfully setup and connected.', + }; + }), + catchError((err) => { + let message = 'Bitmovin: '; + if (err.status) message += err.status + ' '; + if (err.statusText) { + message += err.statusText; + } else { + message += 'Can not connect to Bitmovin API'; + } + + let errorMessage = err.data?.message || err.data?.data?.message; + + //additional errorDetails like requestId and timestamp if requestId is set + let errorDetails; + if (err.data?.requestId) { + errorDetails = 'Timestamp: ' + new Date().toISOString(); + errorDetails += err.data?.requestId ? '\nRequestId: ' + err.data?.requestId : ''; + } - if (response.status === 200) { - return { - status: 'success', - message: 'Datasource setup successfully.', - }; - } else { - return { - status: 'error', - message: response.statusText - ? response.statusText - : 'An unexpected error occurred. Datasource not setup correctly.', - }; - } + return of({ + status: 'error', + message: message, + details: { message: errorMessage, verboseMessage: errorDetails }, + }); + }) + ) + ); } }