forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PMM-12840 Move PT Summary to main repo
- Loading branch information
1 parent
9389120
commit 9ccb39e
Showing
22 changed files
with
497 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
public/app/percona/shared/services/actions/Actions.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { apiManagement } from '../../helpers/api'; | ||
|
||
import { ActionRequest, ActionResponse } from './Actions.types'; | ||
|
||
export const ActionsService = { | ||
getActionResult<T>(body: ActionRequest) { | ||
return apiManagement.post<ActionResponse<T>, ActionRequest>('/Actions/Get', body); | ||
}, | ||
}; |
15 changes: 15 additions & 0 deletions
15
public/app/percona/shared/services/actions/Actions.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export interface ActionResult<T = object> { | ||
error: string; | ||
loading: boolean; | ||
value: T | null; | ||
} | ||
|
||
export interface ActionRequest { | ||
action_id: string; | ||
} | ||
|
||
export interface ActionResponse<T = object> { | ||
done: boolean; | ||
error: string; | ||
output: T; | ||
} |
50 changes: 50 additions & 0 deletions
50
public/app/percona/shared/services/actions/Actions.utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { backOff } from 'exponential-backoff'; | ||
|
||
import { ActionsService } from './Actions.service'; | ||
import { ActionResult } from './Actions.types'; | ||
|
||
const INTERVAL = 500; | ||
|
||
export const getActionResult = async <T>(actionId: string): Promise<ActionResult<T>> => { | ||
const getData = async () => { | ||
const result = await ActionsService.getActionResult<T>({ | ||
action_id: actionId, | ||
}); | ||
|
||
if (!result.done && !result.error) { | ||
throw Error(''); | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
let requestResult; | ||
|
||
try { | ||
requestResult = await backOff(() => getData(), { | ||
startingDelay: INTERVAL, | ||
numOfAttempts: 10, | ||
delayFirstAttempt: false, | ||
}); | ||
} catch (e) { | ||
return { | ||
loading: false, | ||
value: null, | ||
error: 'Unknown error', | ||
}; | ||
} | ||
|
||
if (requestResult.error) { | ||
return { | ||
loading: false, | ||
value: requestResult.output, | ||
error: requestResult.error, | ||
}; | ||
} | ||
|
||
return { | ||
loading: false, | ||
value: requestResult.output, | ||
error: '', | ||
}; | ||
}; |
33 changes: 33 additions & 0 deletions
33
public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { getTemplateSrv } from '@grafana/runtime'; | ||
import { apiManagement } from 'app/percona/shared/helpers/api'; | ||
|
||
import { PTSummaryRequest, PTSummaryResponse, DatabaseSummaryRequest } from './PTSummary.types'; | ||
|
||
export const PTSummaryService = { | ||
async getPTSummary(variableName: string) { | ||
const body: PTSummaryRequest = { node_id: getTemplateSrv().replace(`$${variableName || 'node_id'}`) }; | ||
|
||
return apiManagement.post<PTSummaryResponse, any>('/Actions/StartPTSummary', body, true); | ||
}, | ||
async getMysqlPTSummary(variableName: string) { | ||
const body: DatabaseSummaryRequest = { | ||
service_id: getTemplateSrv().replace(`$${variableName || 'service_name'}`), | ||
}; | ||
|
||
return apiManagement.post<PTSummaryResponse, any>('/Actions/StartPTMySQLSummary', body, true); | ||
}, | ||
async getPostgresqlPTSummary(variableName: string) { | ||
const body: DatabaseSummaryRequest = { | ||
service_id: getTemplateSrv().replace(`$${variableName || 'service_name'}`), | ||
}; | ||
|
||
return apiManagement.post<PTSummaryResponse, any>('/Actions/StartPTPgSummary', body, true); | ||
}, | ||
async getMongodbPTSummary(variableName: string) { | ||
const body: DatabaseSummaryRequest = { | ||
service_id: getTemplateSrv().replace(`$${variableName || 'service-name'}`), | ||
}; | ||
|
||
return apiManagement.post<PTSummaryResponse, any>('/Actions/StartPTMongoDBSummary', body, true); | ||
}, | ||
}; |
19 changes: 19 additions & 0 deletions
19
public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummary.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export interface PTSummaryRequest { | ||
node_id: string; | ||
} | ||
|
||
export interface DatabaseSummaryRequest { | ||
service_id: string; | ||
} | ||
|
||
export interface PTSummaryResponse { | ||
action_id: string; | ||
pmm_agent_id: string; | ||
} | ||
|
||
export enum DatasourceType { | ||
postgresql = 'postgresql', | ||
mongodb = 'mongodb', | ||
mysql = 'mysql', | ||
node = 'node', | ||
} |
99 changes: 99 additions & 0 deletions
99
public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { FieldType, toDataFrame } from '@grafana/data'; | ||
import { ActionResult } from 'app/percona/shared/services/actions/Actions.types'; | ||
|
||
import { PTSummaryService } from './PTSummary.service'; | ||
import { PTSummaryDataSource } from './PTSummaryDataSource'; | ||
|
||
jest.mock('@grafana/runtime', () => ({ | ||
getTemplateSrv: () => ({ | ||
replace: () => 'node', | ||
}), | ||
})); | ||
jest.mock('app/percona/shared/services/actions/Actions.utils', () => ({ | ||
getActionResult: async (): Promise<ActionResult<string>> => | ||
new Promise((resolve) => { | ||
resolve({ | ||
loading: false, | ||
value: 'Test data', | ||
error: '', | ||
}); | ||
}), | ||
})); | ||
|
||
describe('PTSummaryDatasource::', () => { | ||
it('Returns correct data for Node summary', async () => { | ||
const expected = { | ||
data: [ | ||
toDataFrame({ | ||
fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], | ||
}), | ||
], | ||
}; | ||
const instance = new PTSummaryDataSource({}); | ||
|
||
PTSummaryService.getPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); | ||
|
||
const result = await instance.query({ | ||
targets: [{ refId: 'A', queryType: { type: 'node', variableName: undefined } }], | ||
} as any); | ||
|
||
expect(result).toEqual(expected); | ||
}); | ||
|
||
it('Returns correct data for MySQL summary', async () => { | ||
const expected = { | ||
data: [ | ||
toDataFrame({ | ||
fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], | ||
}), | ||
], | ||
}; | ||
const instance = new PTSummaryDataSource({}); | ||
|
||
PTSummaryService.getMysqlPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); | ||
|
||
const result = await instance.query({ | ||
targets: [{ refId: 'A', queryType: { type: 'mysql', variableName: undefined } }], | ||
} as any); | ||
|
||
expect(result).toEqual(expected); | ||
}); | ||
|
||
it('Returns correct data for MongoDB summary', async () => { | ||
const expected = { | ||
data: [ | ||
toDataFrame({ | ||
fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], | ||
}), | ||
], | ||
}; | ||
const instance = new PTSummaryDataSource({}); | ||
|
||
PTSummaryService.getMongodbPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); | ||
|
||
const result = await instance.query({ | ||
targets: [{ refId: 'A', queryType: { type: 'mongodb', variableName: undefined } }], | ||
} as any); | ||
|
||
expect(result).toEqual(expected); | ||
}); | ||
|
||
it('Returns correct data for PostgreSQL summary', async () => { | ||
const expected = { | ||
data: [ | ||
toDataFrame({ | ||
fields: [{ name: 'summary', values: ['Test data'], type: FieldType.string }], | ||
}), | ||
], | ||
}; | ||
const instance = new PTSummaryDataSource({}); | ||
|
||
PTSummaryService.getPostgresqlPTSummary = jest.fn().mockResolvedValueOnce({ value: 'Test data' }); | ||
|
||
const result = await instance.query({ | ||
targets: [{ refId: 'A', queryType: { type: 'postgresql', variableName: undefined } }], | ||
} as any); | ||
|
||
expect(result).toEqual(expected); | ||
}); | ||
}); |
61 changes: 61 additions & 0 deletions
61
public/app/plugins/datasource/pmm-pt-summary-datasource/PTSummaryDataSource.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { DataQueryResponse, DataSourceApi, toDataFrame, FieldType } from '@grafana/data'; | ||
import { getActionResult } from 'app/percona/shared/services/actions/Actions.utils'; | ||
|
||
import { PTSummaryService } from './PTSummary.service'; | ||
import { DatasourceType, PTSummaryResponse } from './PTSummary.types'; | ||
|
||
export class PTSummaryDataSource extends DataSourceApi { | ||
constructor(instanceSettings: any) { | ||
super(instanceSettings); | ||
} | ||
|
||
async query(options: any): Promise<DataQueryResponse> { | ||
const { variableName, type } = options.targets[0]?.queryType || {}; | ||
|
||
const getRequest = (type: DatasourceType) => { | ||
switch (type) { | ||
case DatasourceType.node: | ||
return PTSummaryService.getPTSummary(variableName); | ||
case DatasourceType.mysql: | ||
return PTSummaryService.getMysqlPTSummary(variableName); | ||
case DatasourceType.mongodb: | ||
return PTSummaryService.getMongodbPTSummary(variableName); | ||
case DatasourceType.postgresql: | ||
return PTSummaryService.getPostgresqlPTSummary(variableName); | ||
default: | ||
return PTSummaryService.getPTSummary(variableName); | ||
} | ||
}; | ||
|
||
return getRequest(type) | ||
.then(async (response) => { | ||
const result = await getActionResult<string>((response as PTSummaryResponse).action_id); | ||
|
||
return this.newDataFrame(result.value ? result.value : result.error); | ||
}) | ||
.catch((error) => this.newDataFrame(error.response.data.message)); | ||
} | ||
|
||
async testDatasource() { | ||
return { | ||
status: 'success', | ||
message: 'Success', | ||
}; | ||
} | ||
|
||
newDataFrame(value: string) { | ||
return { | ||
data: [ | ||
toDataFrame({ | ||
fields: [ | ||
{ | ||
name: 'summary', | ||
values: [value], | ||
type: FieldType.string, | ||
}, | ||
], | ||
}), | ||
], | ||
}; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { DatasourceType } from '../PTSummary.types'; | ||
|
||
import { Messages } from './QueryEditor.messages'; | ||
|
||
|
||
export const DATASOURCES = [ | ||
{ | ||
value: DatasourceType.node, | ||
label: Messages.labels.nodePTSummary, | ||
}, | ||
{ | ||
value: DatasourceType.mysql, | ||
label: Messages.labels.mysqlPTSummary, | ||
}, | ||
{ | ||
value: DatasourceType.postgresql, | ||
label: Messages.labels.postgresqlPTSummary, | ||
}, | ||
{ | ||
value: DatasourceType.mongodb, | ||
label: Messages.labels.mongodbPTSummary, | ||
}, | ||
]; |
15 changes: 15 additions & 0 deletions
15
public/app/plugins/datasource/pmm-pt-summary-datasource/QueryEditor/QueryEditor.messages.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export const Messages = { | ||
labels: { | ||
postgresqlPTSummary: 'PostgreSQL PT Summary', | ||
mongodbPTSummary: 'MongoDB PT Summary', | ||
mysqlPTSummary: 'MySQL PT Summary', | ||
nodePTSummary: 'Node PT Summary', | ||
field: { | ||
datasourceType: 'Datasource type', | ||
variableName: 'Grafana variable name', | ||
}, | ||
}, | ||
placeholders: { | ||
variableName: 'Variable name', | ||
}, | ||
}; |
Oops, something went wrong.