-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
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 JENKINS-35845] Internationalisation for Blue Ocean and JDL #2586
Conversation
Signed-off-by: Thorsten Scherler <[email protected]>
Currently issues a 200 with an "error" response payload. This change still issues the error response payload, but also sets the HTTP response. Signed-off-by: Thorsten Scherler <[email protected]>
This pull request originates from a CloudBees employee. At CloudBees, we require that all pull requests be reviewed by other CloudBees employees before we seek to have the change accepted. If you want to learn more about our process please see this explanation. |
@tfennelly can you have a look on the above since you appear the original author. |
} catch (Exception e) { | ||
return HttpResponses.errorJSON(e.getMessage()); | ||
return HttpResponses.errorJSON(e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
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.
I see what you are doing here and it makes sense, but strictly speaking is not needed for fixing the issue wrt loading bundles from plugins, or am I missing something?
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.
+1
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.
@tfennelly you are right strictly this is not needed.
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.
Better to submit as a separate PR then
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.
I will refactor to drop the part on SC_INTERNAL_SERVER_ERROR
} | ||
} | ||
} | ||
} |
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.
I wonder should we be specifying the actual plugin name as a parameter on the rest endpoint?
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.
I suppose this is ok ... keeps the code more simple and is only executed once (if the bundle is not in the cache).
JSONObject response = jenkinsRule.getJSON("i18n/resourceBundle?baseName=com.acme.XyzWhatever").getJSONObject(); | ||
} catch (Exception e) { | ||
Assert.assertNotNull(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.
Hmmm .... maybe check for something more specific?
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.
I just looked and I think you should get a HtmlUnit exception (FailingHttpStatusCodeException
I think) that you can check i.e. check for an expected exception Vs just any exception. If it is FailingHttpStatusCodeException
, you should still be able to get the actual response and perform the same checks that were removed, I think.
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.
I do not feel this test is enough for the change
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.
Several 🐜s in the implementation and definitely not enough tests. IIMHO 🐛
* | ||
* @since TODO | ||
*/ | ||
public static HttpResponse errorJSON(@Nonnull String message, int errorCode) { |
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.
Maybe YAGNI, but OK
* @param statusCode The status code. | ||
* @return {@link this} object. | ||
*/ | ||
public JSONObjectResponse setStatusCode(Integer statusCode) { |
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.
Maybe withStatusCode()
?
@@ -109,6 +121,7 @@ public static HttpResponse errorJSON(@Nonnull String message) { | |||
private static final Charset UTF8 = Charset.forName("UTF-8"); | |||
|
|||
private final JSONObject jsonObject; | |||
private Integer statusCode; |
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.
🐜 Add @CheckForNull
.
if (bundle == null) { | ||
// Not in Jenkins core. Check the plugins. | ||
Jenkins jenkins = Jenkins.getInstance(); | ||
if (jenkins != 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.
This check is not required
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.
Actually it is @oleg-nenashev the failure you have linked is provoked by that test not being in place anymore.
// Not in Jenkins core. Check the plugins. | ||
Jenkins jenkins = Jenkins.getInstance(); | ||
if (jenkins != null) { | ||
for (PluginWrapper plugin : jenkins.getPluginManager().getPlugins()) { |
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.
Ideally needs to be optimized. IIRC baseName usually contains /plugin/myPlugin, which may tweak the performance
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.
not sure how to optimize though, some hints?
|
||
bundleJSON = toJSONObject(bundle); | ||
bundles.put(bundleKey, bundleJSON); | ||
|
||
return bundleJSON; | ||
} | ||
|
||
private static ResourceBundle getBundle(String baseName, Locale locale, ClassLoader classLoader) { |
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.
🐜 Add @ChewckForNull
to return value and parameters if they are nullable
JSONObject response = jenkinsRule.getJSON("i18n/resourceBundle?baseName=com.acme.XyzWhatever").getJSONObject(); | ||
} catch (Exception e) { | ||
Assert.assertNotNull(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.
I do not feel this test is enough for the change
… get the translations from the standard jenkins way, but needs changes in the core for now
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.
@oleg-nenashev I have created another test and fixed your comments.
// Not in Jenkins core. Check the plugins. | ||
Jenkins jenkins = Jenkins.getInstance(); | ||
if (jenkins != null) { | ||
for (PluginWrapper plugin : jenkins.getPluginManager().getPlugins()) { |
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.
not sure how to optimize though, some hints?
@@ -23,28 +23,30 @@ | |||
*/ | |||
package hudson.util; | |||
|
|||
import java.io.File; |
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.
Please never use IDE's autoformat :(
* @param statusCode The status code. | ||
* @return {@link this} object. | ||
*/ | ||
public JSONObjectResponse withStatusCode(Integer statusCode) { |
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.
Also @CheckForNull
for parameter? NIT
} catch (Exception e) { | ||
return HttpResponses.errorJSON(e.getMessage()); | ||
return HttpResponses.errorJSON(e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
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.
+1
* @return The bundle JSON. | ||
* @throws MissingResourceException Missing resource bundle. | ||
*/ | ||
private static @Nullable |
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.
Strange formatting
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.
Should be CheckForNull since it may happen on a common path
try { | ||
return ResourceBundle.getBundle(baseName, locale, classLoader); | ||
} catch (MissingResourceException e) { | ||
// fall through and return 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.
🐜 Must go to system log
* @param locale The Locale. | ||
* @param classLoader The classLoader | ||
* @return The bundle JSON. | ||
* @throws MissingResourceException Missing resource bundle. |
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.
🐛 It's not being thrown from the method
@oleg-nenashev fixed your feedback |
Still 🐜 for unrelated formatting changes, but the changes itself LGTM. 🐝 |
@oleg-nenashev fixed all not releated formating changes |
Test failure seems to be related. The logic causes NPE: https://ci.jenkins.io/job/Core/job/jenkins/job/PR-2586/9/testReport/jenkins.util/ResourceBundleUtilTest/test_unknown_bundle/ |
* @param classLoader The classLoader | ||
* @return The bundle JSON. | ||
*/ | ||
private static @CheckForNull ResourceBundle getBundle(@Nonnull String baseName, @Nonnull Locale locale, @Nonnull ClassLoader classLoader) { |
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.
Well, @jglick-style violates the recommended code style
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.
@oleg-nenashev not sure what you mean
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.
Well...
Style defined in https://wiki.jenkins-ci.org/display/JENKINS/Beginners+Guide+to+Contributing#BeginnersGuidetoContributing-CodeStyle
@CheckForNull
private static ResourceBundle getBundle(@Nonnull String baseName, @Nonnull Locale locale, @Nonnull ClassLoader classLoader)
jglick-style:
private static @CheckForNull ResourceBundle getBundle(@Nonnull String baseName, @Nonnull Locale locale, @Nonnull ClassLoader classLoader)
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.
@oleg-nenashev ok got ya, so should I fix the other occurrence of that in the file?
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.
Yep, the file contains only one annotation style.
Then I'd just keep it as is and then perform a bulk refactoring when Jesse goes to a vacation without internet access :)
return ResourceBundle.getBundle(baseName, locale, classLoader); | ||
} catch (MissingResourceException e) { | ||
// fall through and return null. | ||
logger.info(e.getMessage()); |
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.
Add error to the logged message. Likely INFO is a bad logging level since it's an expected behavior sometimes. Will pollute logs
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.
will do
…le test by prevent NPE to happen
@oleg-nenashev your feedback is in this PR now. |
@oleg-nenashev ping |
} | ||
|
||
@Test | ||
public void test_baseName_plugin() throws IOException, SAXException { |
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.
Nice2have: Add @Issue()
reference
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.
Looks good to me 🐝
re-:bee: |
🐝 |
@reviewbybees done |
Merging in order to get the fix in the next weekly. |
return ResourceBundle.getBundle(baseName, locale, classLoader); | ||
} catch (MissingResourceException e) { | ||
// fall through and return null. | ||
logger.warning(e.getMessage()); |
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.
Does this really deserves warning? IIUC it is ok if particular plugin just does not provide it.
In case no plugin provide it we will have one exception thrown and N warning records logged. If it is provided in the last plugin, there will be N-1 warnings for no reason.
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.
I think we just need to reduce the message severity to the FINE or FINEST level
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.
@oleg-nenashev is this the only update that is blocking this from backporting?
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.
"Blocking" - maybe. But we still need to agree regarding the feasibility of the backporting
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.
Wait, will this print an average of dozens of messages every time a non-core resource is searched? It iterates over all plugins… If so, this should be changed in master as well.
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.
Yes, it should. Creating the issue
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.
@i386, this is the only thing that made me hesitate with backporting this. It will go in with oleg's tuning. |
* Load i18n resource bundles from plugins if not found in jenkins core Signed-off-by: Thorsten Scherler <[email protected]> * Issue 404 response for missing i18n resource bundles Currently issues a 200 with an "error" response payload. This change still issues the error response payload, but also sets the HTTP response. Signed-off-by: Thorsten Scherler <[email protected]> * [JENKINS-35845] Fix test since we return now a 404 * [JENKINS-35845] add test for getting locale from plugin. fix comments from oleg. * [JENKINS-35845] Fix description * [JENKINS-35845] Update PR with comments from Oleg * [JENKINS-35845] Add feedback from tom * eslint - formating changes and fix offences * eslint - formating changes and fix offences * [JENKINS-35845] remove code concerning 404 response. Fix resourceBundle test by prevent NPE to happen * [JENKINS-35845] Link to issue on which we introduced the test (cherry picked from commit ab16e52)
* [JENKINS-35845] WIP first steps with i18n * eslint - formating changes and fix offences * [JENKINS-35845] first basic working version with 2 languages * [JENKINS-35845] WIP adding patched backend to investigate * [JENKINS-35845] Assumes jenkinsci/jenkins#2586 to be applied. We know get the translations from the standard jenkins way, but needs changes in the core for now * [JENKINS-35845] remove testing class * [JENKINS-35845] WIP fixing integration of jenkins i18n keys with dot in them * [JENKINS-35845] move i18n to core-js and using it from within web * [JENKINS-35845] follow jenkins convention/pattern for storing locale * [JENKINS-35845] WIP implement translation in core-js runbutton and toastUtil. Prefix translations with bo.web. remove sample code * [JENKINS-35845] WIP starting to translate dashboard * [JENKINS-35845] WIP added german translation and finished dashboard. Currently working on making moment respect the locale * [JENKINS-35845] Use latest jdl * [JENKINS-35845] fix locale retrieval * [JENKINS-35845] update stories to use the new i18n functions. Create story to test readableDate and timeDuration. In node this works fine now traking down wht not in dashboard * [JENKINS-35845] Add spanish translations * [JENKINS-35845] better translation for spanish (thank you @Dario) as well updated some german translations * [JENKINS-35845] Fix german translations with feedback from @daniel * [JENKINS-35845] Fix test view and finish translation * [JENKINS-35845] Fix german translation. fix result views. fix some lint issues. * [JENKINS-35845] create a compose function to wire different functions together * [JENKINS-35845] better documentation and remove debug string * [JENKINS-35845] add documentation about i18n and linking contributing and i18n docu in principal readme. * [JENKINS-35845] updte docu * [JENKINS-35845] Pass locale and translation function down the component tree. Fix links to not drop query parameters. * [JENKINS-35845] Fix links to not drop query * [JENKINS-35845] use the url config util to get correct path to jenkins * [JENKINS-35845] WIP security commit - refactor i18n class to support listener and subscribe to i18nChanges. Will allow to drop react specific integration via react-i18next. * [JENKINS-35845] WIP security commit * [JENKINS-35845] remove debug statement * [JENKINS-35845] fix import * Task/jenkins 35845 i18n key rename (#579) * [JENKINS-35845] rework i18n keys for home page * [JENKINS-35845] l10n for activity tab * [JENKINS-35845] l10n for branches tab * [JENKINS-35845] l10n for pull requests tab * [JENKINS-35845] l10n for run details -> pipeline * [JENKINS-35845] l10n for run details -> changes, tests, artifacts * [JENKINS-35845] l10n for run details header changes * [JENKINS-35845] pagination; fix typo causing error * [JENKINS-35845] order keys * [JENKINS-35845] WIP security commit to be able to merge master * eslint - formating changes and fix offences * [JENKINS-35845] Remove dep to snapshot-jenkins and implement fallback to default values. Fix tests of all related projects. * [JENKINS-35845] remove duplicate variable * [JENKINS-35845] fix test by adding polyfy again * eslint - formating changes and fix offences * [JENKINS-35845] Fix last test * [JENKINS-35845] fix tests for dashboard * [JENKINS-35845] sync version numbers
Allow plugins to export i18n resources.
Alternative to #2400 related to JENKINS-35270.
Created the PR because of [JENKINS-35845] Internationalisation for Blue Ocean and JDL
@jenkinsci/code-reviewers @reviewbybees