-
Notifications
You must be signed in to change notification settings - Fork 271
(fix) Fetch all backend modules in implementer tools when count exceeds page limit #1463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ODORA0! Just a couple of nits and it should be ok.
| nextUrl = resolveNext(nextLink ? nextLink.uri || nextLink.href || null : null); | ||
| safetyCounter += 1; | ||
| } catch (e) { | ||
| console.error('Failed to fetch installed backend modules page', e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to include more details like what page we were trying to fetch, etc.
| const collected: Array<BackendModule> = []; | ||
| let nextUrl: string | null = `${restBaseUrl}/module?v=default`; | ||
| let safetyCounter = 0; | ||
| const MAX_PAGES = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is actually intended as a const it should be defined outside the function. Otherwise, just call this maxPages.
|
|
||
| // Use moduleid/moduleId for name matching against required dependency keys (e.g., 'reporting') | ||
| const pageResults: Array<BackendModule> = rawResults.map((r) => ({ | ||
| uuid: r.moduleId ?? r.moduleid ?? r.uuid, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the API can return moduleId (but never moduleid), we're always requesting the default view where the property will always be uuid
| uuid: r.moduleId ?? r.moduleid ?? r.uuid, | |
| uuid: r.uuid, |
| const links: Array<{ rel?: string; uri?: string; href?: string }> = Array.isArray(data?.links) ? data.links : []; | ||
| const nextLink = links.find((l) => (l.rel || '').toLowerCase() === 'next'); | ||
|
|
||
| nextUrl = resolveNext(nextLink ? nextLink.uri || nextLink.href || null : null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the REST API, we always return the property uri if anything.
| nextUrl = resolveNext(nextLink ? nextLink.uri || nextLink.href || null : null); | |
| nextUrl = resolveNext(nextLink?.uri ?? null); |
...ages/apps/esm-implementer-tools-app/src/backend-dependencies/openmrs-backend-dependencies.ts
Show resolved
Hide resolved
| }); | ||
| async function fetchInstalledBackendModules(): Promise<Array<BackendModule>> { | ||
| const collected: Array<BackendModule> = []; | ||
| let nextUrl: string | null = `${restBaseUrl}/module?v=default`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let nextUrl: string | null = `${restBaseUrl}/module?v=default`; | |
| let nextUrl: string | null = `${restBaseUrl}/module?v=custom:(uuid,version)`; |
Can we whittle the custom representation down to just fetching the uuid and version properties? That substantially reduces the payload size from ~10 fields per module down to just 2. The response would look like this:
{
"results": [
{
"uuid": "serialization.xstream",
"version": "0.2.16"
},
{
"uuid": "authentication",
"version": "2.0.0-SNAPSHOT"
},
{
"uuid": "fhir2",
"version": "2.8.0-SNAPSHOT"
}
]
}versus this in the default response:
{
"results": [
{
"uuid": "serialization.xstream",
"display": "Serialization Xstream",
"name": "Serialization Xstream",
"description": "Core (de)serialize API and services supported by xstream library",
"version": "0.2.16",
"started": true,
"startupErrorMessage": null,
"links": [
{
"rel": "full",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/serialization.xstream?v=full",
"resourceAlias": "module"
},
{
"rel": "ref",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/serialization.xstream?v=ref",
"resourceAlias": "module"
},
{
"rel": "action",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/moduleaction",
"resourceAlias": "module"
},
{
"rel": "self",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/serialization.xstream",
"resourceAlias": "module"
}
],
"resourceVersion": "1.8"
},
{
"uuid": "authentication",
"display": "Authentication",
"name": "Authentication",
"description": "Authentication support for OpenMRS",
"version": "2.0.0-SNAPSHOT",
"started": true,
"startupErrorMessage": null,
"links": [
{
"rel": "full",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/authentication?v=full",
"resourceAlias": "module"
},
{
"rel": "ref",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/authentication?v=ref",
"resourceAlias": "module"
},
{
"rel": "action",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/moduleaction",
"resourceAlias": "module"
},
{
"rel": "self",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/authentication",
"resourceAlias": "module"
}
],
"resourceVersion": "1.8"
},
{
"uuid": "fhir2",
"display": "FHIR2",
"name": "FHIR2",
"description": "Implementation of FHIR R4 for OpenMRS",
"version": "2.8.0-SNAPSHOT",
"started": true,
"startupErrorMessage": null,
"links": [
{
"rel": "full",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/fhir2?v=full",
"resourceAlias": "module"
},
{
"rel": "ref",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/fhir2?v=ref",
"resourceAlias": "module"
},
{
"rel": "action",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/moduleaction",
"resourceAlias": "module"
},
{
"rel": "self",
"uri": "https://dev3.openmrs.org/openmrs/ws/rest/v1/module/fhir2",
"resourceAlias": "module"
}
],
"resourceVersion": "1.8"
}
]
}| const { data } = await openmrsFetch(nextUrl, { method: 'GET' }); | ||
| const rawResults: Array<any> = Array.isArray(data?.results) ? data.results : []; | ||
|
|
||
| // Use moduleid/moduleId for name matching against required dependency keys (e.g., 'reporting') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Use moduleid/moduleId for name matching against required dependency keys (e.g., 'reporting') |
This is misleading because the API's uuid field already contains module IDs like "webservices.rest". The moduleId/moduleid fields don't exist in the API response.
| while (nextUrl && safetyCounter < MAX_PAGES) { | ||
| try { | ||
| const { data } = await openmrsFetch(nextUrl, { method: 'GET' }); | ||
| const rawResults: Array<any> = Array.isArray(data?.results) ? data.results : []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const rawResults: Array<any> = Array.isArray(data?.results) ? data.results : []; | |
| const rawResults: Array<BackendModule> = Array.isArray(data?.results) ? data.results : []; |
4cc5468 to
7307a9e
Compare
…rect moduleId mapping
…mproved error handling
7307a9e to
93ece0d
Compare
35053b7 to
14f7664
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @ODORA0!
Requirements
feat,fix, orchore, among others). See existing PR titles for inspiration.If applicable
Summary
fetchInstalledBackendModulesto followlinks[rel="next"]until exhaustednextURLs to prevent broken fetchesv=defaultrepresentation to avoid 400 Bad Request errors on some serversuuidfor proper dependency matchingScreenshots
Related Issue
Other