Migrate configurator/upgrade wizard from Apache Click to Jakarta Servlets + FreeMarker#1062
Conversation
…k to FreeMarker transition
Review summarySolid, carefully-executed migration — retires the abandoned vendored Click fork (~36k LOC) for a small servlet + FreeMarker stack while preserving URLs, the AJAX-validation contract, and the Security — clear
Findings
Nicely done
Recommend the render smoke tests before merge given this is the install/upgrade bootstrap path; #2–#4 are nice-to-haves. Manual fresh-install + upgrade walkthrough still worth doing. |
vharseko
left a comment
There was a problem hiding this comment.
Review — Click → Jakarta Servlets + FreeMarker migration
I focused on the real review surface (the new servlet infrastructure, the ported wizard pages and templates), checking behavior against the originals on master rather than the ~36k lines of deleted vendored Click fork.
Verdict: no blocking bugs or regressions found. This is a careful, behavior-preserving migration with good test coverage. A few cosmetic leftovers and hardening opportunities below; none are merge blockers.
What holds up well
- Reflection dispatch is safely gated.
ConfiguratorServlet.findActiononly resolves methods annotated with@ConfiguratorAction, so a request cannot invoke an arbitrary public method. UnknownactionLink→ 404, unregistered path → 404. - FreeMarker's null-strictness is handled systematically. Velocity rendered a missing
$fooas a literal; FreeMarker${foo}withRETHROW_HANDLERthrows. Pages either always populate values (getAttribute(..., default)) or templates guard with${x!""}/<#if x??>. The trickiest page,step3.ftl(${type},<#if store.password??>), is covered because both come fromLDAPStoreWizardPage.onInit()(type="config", andstoreis never null viaensureConfig()). This is backstopped byConfiguratorServletRenderSmokeTest, which renders all 10 pages and asserts no exception. - Security posture is faithfully ported.
ProtectedSetupPage.onSecurityCheck()reproduces the oldProtectedPagere-entry guard (AMSetupServlet.isConfigured());Optionsdeliberately extendsSetupPagewithout a guard, matching the oldOptions extends TemplatedPage. - Routing / downstream registration are clean.
web.xmlswapsclick-servlet→configurator-servleton*.htm;Upgrade(inopenam-upgrade) self-registers viaServiceLoader/META-INF/services(same idiom asSetupListener), avoiding a Maven cycle. No dangling references to the removedopenidentityplatform.openam.clickpackage remain in live code. - Prior review rounds already fixed real issues (NPE in
checkPasswords, JSON escaping viaJSONObject,TemplateExceptionHandler).
Minor cleanup (worth doing in this PR)
- Stale WAR manifests.
fam-console.list#L1239andfam-noconsole.list#L1334still listWEB-INF/click.xmlandWEB-INF/classes/click-page.properties, which this PR deletes. The build doesn't break (only the legacy Antsrc/main/previous_scripts/build.xmlreads these), but the lists are now inaccurate. - Stale docs.
chap-endpoints.adoc/chap-endpoints.xmlstill describe theclick-servletendpoint. copyPublicFieldsprecedence.ConfiguratorServlet.copyPublicFieldsruns after the model is seeded fromgetModel(), so a public field silently overrides anaddModelentry of the same name. Harmless today (values coincide), but a latent footgun — a comment would help.
Observations — pre-existing, not introduced by this PR (no action required here)
- No FreeMarker HTML auto-escaping. Form values (
serverURL,configStoreHost,rootSuffix, LDAP hosts,step3.ftlpassword intovalue=, and thestep7summary) render unescaped — exactly as the old Velocity$foodid. Not a regression, and these pages run pre-configuration. But since this is a rewrite it's a natural place to considerHTMLOutputFormat. Caveat: it can't be a blind flip — some templates intentionally inject HTML built in Java (e.g.Step2'sinitialCheck), which would need?no_esc. Reasonable to defer to a follow-up. validateInputsets an arbitrary session attribute from requestkey/value— a faithful port of the oldAjaxPage. SeeSetupPage.validateInput. Low risk within the setup wizard's trust model.- Dead
pushConfig/testNewInstanceUrlaction paths.wizard.ftl#L157still callsactionLink=pushConfig, but no handler exists → 404. The oldWizard.javaonly hadActionLinkfields pointing at methods that were never defined (onlycreateConfig()had a body), so this path was already broken (Click would have errored). Carried over as-is; a 404 now instead of a 500. step7summaryembeddedcheck.step7.ftl#L24<#if embedded??>is never true becauseStep7.java#L57addsisEmbedded, notembedded— but the oldstep7.htmhad the identical#if($embedded)vsadd("isEmbedded",...)mismatch. Faithful port of a latent bug.
…om fam-console.list and fam-noconsole.list
…lect changes in servlet association
…clarify behavior and edge cases
… of admin and JMX ports
Review feedback addressed — review 4656516610 @vharsekoThe review found no blocking bugs or regressions and flagged 3 minor cleanups plus 4 pre-existing observations it considered optional. All seven are now resolved on this branch (
Observations #4–#7 were pre-existing (faithful ports of the old Click/Velocity behavior), not regressions introduced by this PR — they were fixed here anyway. Also included: 2fd719c fixes a setup-IT race (waits for the config link to be enabled before clicking) in Ready for review after successful checks |
Summary
Replaces the vendored Apache Click fork powering the OpenAM configurator/upgrade wizard
with plain Jakarta Servlets + FreeMarker templates, removing ~36k LOC of dead/forked
framework code while preserving all existing URLs, AJAX validation behavior, and backend
coupling (
AMSetupServlet,UpgradeServices, OpenDJ).Why
fork of it just for this 13-page wizard.
replacement had to be lightweight and runtime-independent — FreeMarker is already a
managed dependency (used by
openam-oauth2) and pairs cleanly with plain Jakarta servlets.architecture and byte-for-byte URLs, just swap the framework underneath.
What changed
ConfiguratorServlettakes over the wizard's*.htmrouting via a migrated-pageregistry, so migrating a page is a Java-only change (no per-page
web.xmledits).ported from Click templates to FreeMarker
.ftltemplates underWEB-INF/templates/config/....UpgradePageProvider/Upgrade.javaupdated for the new routing.click.xml,click-page.properties,error.htm,not-found.htm, legacystep7.htm.pom.xmlupdated to drop the Click dependency.WizardTest,ConfiguratorServletTest,ServletContextTemplateLoaderTest,UpgradeTest,ConfiguratorServletUpgradeRoutingTest.and FreeMarker running side-by-side (unmigrated pages delegated to the old Click fork via
RequestDispatcher), so the reactor stayed green throughout. Click is fully removed onlyin the final increment.
Testing
upgrade path.
touches the pre-configuration bootstrap path.