-
Notifications
You must be signed in to change notification settings - Fork 358
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
fix: Serving App resource rules (installed apps) [DHIS2-18185] #19923
base: master
Are you sure you want to change the base?
Conversation
dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AppController.java
Dismissed
Show dismissed
Hide dismissed
<dependency> | ||
<groupId>com.google.code.findbugs</groupId> | ||
<artifactId>jsr305</artifactId> | ||
</dependency> |
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.
the project wouldn't build without this (used undeclared dep etc.)
|
||
if (resource == null) { | ||
response.sendError(HttpServletResponse.SC_NOT_FOUND); | ||
ResourceResult resourceResult = appManager.getAppResource(application, resource); |
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.
these results can be handled more nicely when we move to the higher Java version with switch pattern matching
} | ||
response.setHeader("ETag", etag); | ||
StreamUtils.copyThenCloseInputStream(resource.getInputStream(), response.getOutputStream()); | ||
if (resourceResult instanceof Redirect redirect) { |
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.
There were no existing redirect code paths here, so now this has to be handled as a possible result.
// this is due to the complex regex above which has to include '/' at the end, so correct | ||
// app names are matched e.g. dhis-web-user v dhis-web-user-profile | ||
serveInstalledAppResource( | ||
app, resourcePath.isBlank() ? "/" : resourcePath, request, response); |
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.
this change ensures that the actual resource requested e.g. dhis-web-user-profile/
is correctly matched with resource rule 1a.
dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/ResourceResult.java
Outdated
Show resolved
Hide resolved
...-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java
Outdated
Show resolved
Hide resolved
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.
Great work @david-mackessy, thanks for following this through so thoroughly!
It would be great if @cjmamo and @KaiVandivier could take a look at the code and logic as well before this is merged (mostly to be aware of it, since we'll be looking at general improvements to this app serving infrastructure soon)
dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/AppStorageService.java
Show resolved
Hide resolved
...-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java
Outdated
Show resolved
Hide resolved
...vices/dhis-service-core/src/main/java/org/hisp/dhis/appmanager/JCloudsAppStorageService.java
Show resolved
Hide resolved
|
Issue
The original issue raised was for a
GET
call to/api/apps/line-listing
which resulted in a404
not found, even though the directory/api/apps/line-listing/
existed and had anindex.html
file within.The correct response for a
GET
call to/api/apps/line-listing
(if the directory exists) is a302
redirect with the existing path e.g./api/apps/line-listing/
returned as the location header.Cause
There were multiple issues regarding how we serve app resources:
Fix
The expectations of the server (app resource rules) were provided by @amcgee. This makes things very clear for all involved (Confluence page exists now). They are:
If the requested path ends with
/
a. Respond with contents of
./index.html
if it existsb. Otherwise
404
If the requested path ends with no trailing slash
a. If it exists as a file, return it
200
b. If it exists as a directory, return a
302
redirect to the request path with a/
appendedc. otherwise
404
This fix includes:
/
in places where they were not needed, which resulted in outcomes that were not obvious to the callerSome clean up was done to use the JClouds feature in the way we probably hoped to use it in that we now handle all app resources the same way. Previously we had different code paths for different storage types which defeats the purpose of using the JClouds abstraction.
The changes were kept to a minimum to reduce the possibility of unseen issues. There are not many automated tests for this feature, given that it requires installing apps and then fetching resources.
There are more object storage tests (using MinIO) than file system tests.
The retrieval results for a
Resource
have been modelled (ResourceResult
) to reflect the rules. This should:App resources are retrieved for both
/api/apps/
and/dhis-web-..../
(when installed) endpoints. Both requests come in through different parts of the code. A small change inAppOverrideFilter
has been made so that requests to e.g./dhis-web-user-profile/
come through to app resource rules with a resource path of/
. Previous behaviour was to pass through an empty resource path. This change means both paths have the same rules applied to the actual resource path requested.Testing
Automated
Multiple MinIO tests added for all types of expected scenarios
Some AppManager tests added for resource values
Manual
Tested locally & in IM using installed versions of apps (not bundled which has separate behaviour).
Below is a table of the previous behaviour vs new behaviour for different resource requests. Requests not matching the new resource rules are labelled with
BUG
. They were performed against the following existing directories:PREVIOUS BEHAVIOUR
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
BUG
NEW BEHAVIOUR
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED
FIXED