Collect all available metric types if the number exceeds the default page size of 100

Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com>
This commit is contained in:
Dominik Henneke
2021-03-01 11:50:18 +01:00
parent d7a5bfd57f
commit 4105503885
4 changed files with 54 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sonarqube': patch
---
Collect all available metric types if the number exceeds the default page size of 100.
+1
View File
@@ -41,6 +41,7 @@
"@material-ui/lab": "4.0.0-alpha.45",
"@material-ui/styles": "^4.10.0",
"cross-fetch": "^3.0.6",
"qs": "^6.9.4",
"rc-progress": "^3.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
@@ -45,10 +45,25 @@ describe('SonarQubeClient', () => {
],
) => {
server.use(
rest.get(`${mockBaseUrl}/sonarqube/metrics/search`, (_, res, ctx) => {
rest.get(`${mockBaseUrl}/sonarqube/metrics/search`, (req, res, ctx) => {
expect(req.url.searchParams.get('ps')).toBe('500');
// emulate paging to check if everything is requested
if (req.url.searchParams.get('p') === '1') {
return res(
ctx.json({
metrics: metricKeys.slice(0, 5).map(k => ({ key: k })),
total: 2,
}),
);
}
// make sure this is only called twice
expect(req.url.searchParams.get('p')).toBe('2');
return res(
ctx.json({
metrics: metricKeys.map(k => ({ key: k })),
metrics: metricKeys.slice(5).map(k => ({ key: k })),
total: 2,
}),
);
}),
+31 -14
View File
@@ -16,6 +16,7 @@
import { DiscoveryApi } from '@backstage/core';
import fetch from 'cross-fetch';
import qs from 'qs';
import { FindingSummary, Metrics, SonarQubeApi } from './SonarQubeApi';
import { ComponentWrapper, MeasuresWrapper } from './types';
@@ -34,9 +35,13 @@ export class SonarQubeClient implements SonarQubeApi {
this.baseUrl = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
}
private async callApi<T>(path: string): Promise<T | undefined> {
private async callApi<T>(
path: string,
query?: { [key in string]: any },
): Promise<T | undefined> {
const queryString = query ? `?${qs.stringify(query)}` : '';
const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/sonarqube`;
const response = await fetch(`${apiUrl}/${path}`);
const response = await fetch(`${apiUrl}/${path}${queryString}`);
if (response.status === 200) {
return (await response.json()) as T;
}
@@ -44,10 +49,23 @@ export class SonarQubeClient implements SonarQubeApi {
}
private async getSupportedMetrics(): Promise<string[]> {
const result = await this.callApi<{ metrics: Array<{ key: string }> }>(
'metrics/search',
);
return result?.metrics?.map(m => m.key) ?? [];
const metrics: string[] = [];
let pageSize: number | undefined;
let nextPage: number = 1;
do {
const result = await this.callApi<{
metrics: Array<{ key: string }>;
total: number;
}>('metrics/search', { ps: 500, p: nextPage });
metrics.push(...(result?.metrics?.map(m => m.key) ?? []));
pageSize = result?.total;
nextPage++;
} while (pageSize && nextPage <= pageSize);
return metrics;
}
async getFindingSummary(
@@ -57,9 +75,9 @@ export class SonarQubeClient implements SonarQubeApi {
return undefined;
}
const component = await this.callApi<ComponentWrapper>(
`components/show?component=${componentKey}`,
);
const component = await this.callApi<ComponentWrapper>('components/show', {
component: componentKey,
});
if (!component) {
return undefined;
}
@@ -84,11 +102,10 @@ export class SonarQubeClient implements SonarQubeApi {
supportedMetrics.includes(m),
);
const measures = await this.callApi<MeasuresWrapper>(
`measures/search?projectKeys=${componentKey}&metricKeys=${metricKeys.join(
',',
)}`,
);
const measures = await this.callApi<MeasuresWrapper>('measures/search', {
projectKeys: componentKey,
metricKeys: metricKeys.join(','),
});
if (!measures) {
return undefined;
}