Switch to using other link header parser
Signed-off-by: Robert Bunning <rbunning@webstaurantstore.com>
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.61",
|
||||
"@types/parse-link-header": "^2.0.1",
|
||||
"parse-link-header": "^2.0.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -126,7 +126,7 @@ describe('NewRelicClient', () => {
|
||||
headers: new Map<string, string | null>([
|
||||
[
|
||||
'link',
|
||||
'<https://next.page/page2?page=2>; rel="next", <https://badsite.dontgohere>; rel="next"',
|
||||
'<https://next.page/page2?page=2>; rel="next", <https://badsite.dontgohere>; rel="first"',
|
||||
],
|
||||
['otherheader', 'otherValue'],
|
||||
]),
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
FetchApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
import parseLinkHeader from 'parse-link-header';
|
||||
|
||||
export type NewRelicApplication = {
|
||||
id: number;
|
||||
application_summary: NewRelicApplicationSummary;
|
||||
@@ -76,14 +78,8 @@ export interface NewRelicApi {
|
||||
getApplications(): Promise<NewRelicApplications>;
|
||||
}
|
||||
|
||||
interface PaginationInformation {
|
||||
nextPageLink: string;
|
||||
relation: string;
|
||||
}
|
||||
|
||||
interface NewRelicPageReadResult {
|
||||
hasMoreApplications: boolean;
|
||||
pagination: PaginationInformation | undefined;
|
||||
nextPageUrl: string | undefined;
|
||||
applicationsFromReadPage: NewRelicApplication[];
|
||||
}
|
||||
|
||||
@@ -106,20 +102,17 @@ export class NewRelicClient implements NewRelicApi {
|
||||
this.baseUrl = `${proxyUrl}${this.proxyPathBase}/apm/api/applications.json`;
|
||||
}
|
||||
|
||||
let targetUrl = this.baseUrl;
|
||||
let hasNextPage = true;
|
||||
|
||||
try {
|
||||
let applications: NewRelicApplication[] = [];
|
||||
let targetUrl = this.baseUrl;
|
||||
|
||||
do {
|
||||
const { hasMoreApplications, pagination, applicationsFromReadPage } =
|
||||
const { nextPageUrl, applicationsFromReadPage } =
|
||||
await this.fetchNewRelic(targetUrl);
|
||||
|
||||
hasNextPage = hasMoreApplications;
|
||||
targetUrl = hasNextPage ? pagination!.nextPageLink : '';
|
||||
targetUrl = nextPageUrl ?? '';
|
||||
applications = applications.concat(applicationsFromReadPage);
|
||||
} while (hasNextPage);
|
||||
} while (!!targetUrl);
|
||||
|
||||
return { applications };
|
||||
} catch (e) {
|
||||
@@ -143,37 +136,12 @@ export class NewRelicClient implements NewRelicApi {
|
||||
|
||||
const readResponse = responseJson as NewRelicApplications;
|
||||
const linkHeader = response.headers.get('link');
|
||||
const pagination = this.parseLinkHeader(linkHeader);
|
||||
const parseResult = parseLinkHeader(linkHeader);
|
||||
const nextPageNumber = parseResult?.next?.page;
|
||||
|
||||
return {
|
||||
hasMoreApplications: !!(pagination && pagination.relation === 'next'),
|
||||
pagination,
|
||||
nextPageUrl: nextPageNumber && `${this.baseUrl}?page=${nextPageNumber}`,
|
||||
applicationsFromReadPage: readResponse.applications,
|
||||
};
|
||||
}
|
||||
|
||||
private parseLinkHeader(
|
||||
linkHeader: string | null,
|
||||
): PaginationInformation | undefined {
|
||||
if (!linkHeader) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nextRelevantLink = linkHeader.replaceAll(' ', '').split(',')[0];
|
||||
const linkParts = nextRelevantLink.match(/^<.+(\?page=.+)>;rel="(.+)"$/);
|
||||
const nextPageNumber = linkParts?.[1];
|
||||
const relation = linkParts?.[2];
|
||||
|
||||
const nextPageLink = `${this.baseUrl}${nextPageNumber}`;
|
||||
const isValidLink = !!(linkParts && nextPageNumber && relation);
|
||||
|
||||
if (!nextRelevantLink || !isValidLink) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
nextPageLink,
|
||||
relation,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user