Merge pull request #4739 from SDA-SE/feat/sonarqube-missing-metrics

[SonarQube] Collect all available metric types if the number exceeds the default page size of 100
This commit is contained in:
Dominik Henneke
2021-03-01 17:39:17 +01:00
committed by GitHub
3 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.
@@ -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: metricKeys.length,
}),
);
}
// 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: metricKeys.length,
}),
);
}),
+32 -14
View File
@@ -34,9 +34,14 @@ 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 apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/sonarqube`;
const response = await fetch(`${apiUrl}/${path}`);
const response = await fetch(
`${apiUrl}/${path}?${new URLSearchParams(query).toString()}`,
);
if (response.status === 200) {
return (await response.json()) as T;
}
@@ -44,10 +49,24 @@ 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 nextPage: number = 1;
for (;;) {
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) ?? []));
if (result && metrics.length < result.total) {
nextPage++;
continue;
}
return metrics;
}
}
async getFindingSummary(
@@ -57,9 +76,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 +103,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;
}