Make REST context path configurable via openidm.context.path system property#142
Make REST context path configurable via openidm.context.path system property#142
openidm.context.path system property#142Conversation
… system property Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/eb238ff3-61a5-48d1-8e24-75012632d4af Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
openidm.context.path system property
Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/09144507-08e1-47e9-8c8e-fa167bc6fa76 Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/e03b9d05-a47d-47c4-bdba-5f38d059f841 Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
…iles Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/e00159d5-da69-4e8a-be0c-81fd8a547f3c Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR aims to remove hardcoded /openidm REST base-path usage by introducing a configurable REST context path via the openidm.context.path system property (defaulting to /openidm), and refactoring backend/CLI/UI call sites and docs to use that configuration.
Changes:
- Add backend support for a configurable servlet alias and default servlet-filter URL patterns based on
openidm.context.path. - Refactor many UI delegates/views to build REST URLs using
Constants.contextinstead of hardcoding/openidm. - Add/extend docs and add automated tests for the default context path.
Reviewed changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| openidm-zip/src/main/resources/conf/system.properties | Documents the new openidm.context.path setting (commented example). |
| openidm-ui/openidm-ui-common/src/test/qunit/tests/org/forgerock/openidm/ui/common/util/ConstantsTest.js | Adds QUnit assertions for the default Constants.context value and derived prefix. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/workflow/WorkflowDelegate.js | Replaces hardcoded /openidm/... workflow endpoints with "/" + constants.context + .... |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/notifications/NotificationDelegate.js | Uses constants.context when building the notifications endpoint URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/SystemHealthDelegate.js | Uses constants.context for health endpoint base URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/SocialDelegate.js | Uses Constants.context for identityProviders/authentication endpoints. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/SearchDelegate.js | Uses constants.context for the search delegate base URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/ResourceDelegate.js | Uses constants.context for the resource delegate base URL and linkedView endpoint. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/PolicyDelegate.js | Uses constants.context for policy endpoint base URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/InternalUserDelegate.js | Uses constants.context for internal user repo URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/InfoDelegate.js | Uses constants.context for /info/ endpoint base URL. |
| openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/ConfigDelegate.js | Uses constants.context for /config endpoint base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/TaskListView.js | Uses constants.context for workflow task URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/TaskInstanceView.js | Uses constants.context for task/process/user model URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ProcessListView.js | Uses constants.context for process-definition query URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ProcessInstanceView.js | Uses constants.context for workflow and repo/internal/user and diagram URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ProcessHistoryView.js | Uses constants.context for workflow history URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ProcessDefinitionView.js | Uses constants.context for process-definition and diagram URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ProcessDefinitionsView.js | Uses constants.context for process-definition list/query URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/workflow/ActiveProcessesView.js | Uses constants.context for active process URLs and queries. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/user/EditUserView.js | Uses constants.context for managed user reset password endpoint. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/settings/SettingsView.js | Uses Constants.context for maintenance delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/mapping/util/MappingUtils.js | Uses constants.context for repo/links deletion command endpoint. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/mapping/association/DataAssociationManagementView.js | Uses constants.context for reconResults endpoint; adds Constants dependency. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/WorkflowDelegate.js | Uses constants.context for workflow processdefinition delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/SyncDelegate.js | Uses constants.context for sync and repo/link endpoints and mappingDetails endpoint. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/SecurityDelegate.js | Uses constants.context for security delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ScriptDelegate.js | Uses constants.context for script delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/SchedulerDelegate.js | Uses constants.context for scheduler/job delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ReconDelegate.js | Uses constants.context for recon and audit/recon and target object URLs. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/MaintenanceDelegate.js | Uses constants.context for maintenance delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ExternalAccessDelegate.js | Uses constants.context for oauthproxy and external/rest endpoints. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ConnectorDelegate.js | Uses constants.context for system endpoint base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ClusterDelegate.js | Uses constants.context for base cluster delegate URL. |
| openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/AuditDelegate.js | Uses constants.context for audit delegate base URL. |
| openidm-ui/openidm-ui-admin/src/main/js/config/validators/AdminValidators.js | Treats "/" + constants.context as a reserved URL value; updates error message accordingly. |
| openidm-shell/src/main/java/org/forgerock/openidm/shell/impl/RemoteCommandScope.java | Builds the default CLI URL using openidm.context.path when the default URL value is used. |
| openidm-servlet-registrator/src/main/java/org/forgerock/openidm/servletregistration/impl/ServletRegistrationSingleton.java | Derives default servlet-filter URL patterns from openidm.context.path (instead of hardcoded /openidm/*). |
| openidm-doc/src/main/asciidoc/integrators-guide/chap-configuration.adoc | Documents the new openidm.context.path property and configuration examples. |
| openidm-doc/src/main/asciidoc/integrators-guide/appendix-rest.adoc | Adds note that /openidm in examples is the default and can be changed via openidm.context.path. |
| openidm-api-servlet/src/test/java/org/forgerock/openidm/servlet/internal/ServletComponentTest.java | Adds unit tests for default/custom/normalized servlet alias based on system property. |
| openidm-api-servlet/src/main/java/org/forgerock/openidm/servlet/internal/ServletComponent.java | Registers the REST servlet under an alias derived from openidm.context.path (normalized). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| After changing this property, the REST API will be accessible under the new path, for example `\https://localhost:8443/myidm/config`, and the Admin UI and Self-Service UI will automatically use the configured path for all API calls. | ||
|
|
||
| [NOTE] | ||
| ==== | ||
| Changing the context path affects all REST API endpoints, the Admin UI, and the Self-Service UI. Ensure that any external integrations, load balancer rules, or documentation referring to the `/openidm` path are updated accordingly. |
There was a problem hiding this comment.
The statement that the Admin UI and Self-Service UI will “automatically use the configured path for all API calls” appears inaccurate with the current UI implementation: openidm-ui-common/.../util/Constants.js still hardcodes commonConstants.context = "openidm", so changing -Dopenidm.context.path on the JVM won’t update the UI’s REST base path unless additional wiring is added (for example, injecting the context into the UI at runtime or deriving it from window.location). Please either implement that wiring or adjust this documentation to describe the actual behavior/requirements for the UI.
| After changing this property, the REST API will be accessible under the new path, for example `\https://localhost:8443/myidm/config`, and the Admin UI and Self-Service UI will automatically use the configured path for all API calls. | |
| [NOTE] | |
| ==== | |
| Changing the context path affects all REST API endpoints, the Admin UI, and the Self-Service UI. Ensure that any external integrations, load balancer rules, or documentation referring to the `/openidm` path are updated accordingly. | |
| After changing this property, the REST API will be accessible under the new path, for example `\https://localhost:8443/myidm/config`. The Admin UI and Self-Service UI, however, are implemented with a default context path of `/openidm` for their REST calls. To use a custom context path with the UIs, you must either deploy them behind a reverse proxy that maps the public path (for example `/myidm`) to `/openidm` on the OpenIDM server, or customize and rebuild the UI so that it derives the REST base path from the runtime context (for example, `window.location`) or from injected configuration that matches `openidm.context.path`. | |
| [NOTE] | |
| ==== | |
| Changing the context path affects all REST API endpoints. If you expose the Admin UI or Self-Service UI under a custom path, ensure that any external integrations, load balancer rules, or documentation referring to the `/openidm` path are updated accordingly. |
| QUnit.test("Constants.context defaults to 'openidm'", function (assert) { | ||
| assert.equal(Constants.context, "openidm", | ||
| "The default context should be 'openidm'"); | ||
| }); |
There was a problem hiding this comment.
These tests only verify the hardcoded default (Constants.context === "openidm"). The PR goal is configurable REST context paths; please add coverage for a non-default value as well (e.g., verifying delegates build URLs correctly when the context is overridden), which will require providing a supported way to set/override Constants.context in tests and in runtime.
| private static String getUrl(final String url) { | ||
| if (isNotBlank(url)) { | ||
| return url.endsWith("/") ? url : url + "/"; | ||
| return getEffectiveIdmUrl(url.endsWith("/") ? url : url + "/"); |
There was a problem hiding this comment.
getUrl() now always runs the value through getEffectiveIdmUrl(...), which will replace the URL with one derived from openidm.context.path whenever the normalized URL equals IDM_URL_DEFAULT. This means a user explicitly passing --url http://localhost:8080/openidm/ (or .../openidm which gets normalized) can be unexpectedly overridden by the system property. --url should take precedence over the system property; consider only applying getEffectiveIdmUrl when the --url option was not explicitly provided (e.g., by using a sentinel absentValue and treating blank as ‘use default’).
| return getEffectiveIdmUrl(url.endsWith("/") ? url : url + "/"); | |
| return url.endsWith("/") ? url : url + "/"; |
| static final String OPENIDM_CONTEXT_PATH_PROPERTY = "openidm.context.path"; | ||
|
|
||
| /** Default REST context path. */ | ||
| static final String OPENIDM_CONTEXT_PATH_DEFAULT = "/openidm"; |
There was a problem hiding this comment.
The openidm.context.path property name/default and the path-normalization logic are now duplicated in multiple modules/classes (e.g., this component, ServletRegistrationSingleton, and RemoteCommandScope). To avoid drift (e.g., different trimming/validation rules over time), consider centralizing the constant + normalization in a shared location (such as a core utility or ServerConstants/IdentityServer) and reusing it from all call sites.
| static final String OPENIDM_CONTEXT_PATH_PROPERTY = "openidm.context.path"; | |
| /** Default REST context path. */ | |
| static final String OPENIDM_CONTEXT_PATH_DEFAULT = "/openidm"; | |
| static final String OPENIDM_CONTEXT_PATH_PROPERTY = ServerConstants.OPENIDM_CONTEXT_PATH_PROPERTY; | |
| /** Default REST context path. */ | |
| static final String OPENIDM_CONTEXT_PATH_DEFAULT = ServerConstants.OPENIDM_CONTEXT_PATH_DEFAULT; |
appendix-rest.adocandchap-configuration.adocto 2024-2026ServletComponent.java:2024-2025→2024-2026ServletComponentTest.java:2025→2025-2026ServletRegistrationSingleton.java:2024-2025→2024-2026Portions copyright 2026 3A Systems LLC.toRemoteCommandScope.javaPortions copyright 2026 3A Systems LLC.to all 34 JS delegate/view filesOriginal prompt
Problem
The REST context path
/openidmis hardcoded throughout the entire codebase — in Java backend, JavaScript UI delegates, servlet registration, CLI tools, and documentation. This makes it impossible to change the REST API base path (e.g., to/myidm) without modifying source code.As shown in the screenshot, there are 101+ matches in 53+ JS files alone for the hardcoded
"/openidm"string:Requirements
openidm.context.path) with default value/openidm./openidm) and a custom value (e.g.,/myidm).Detailed Plan
1. Backend (Java)
1.1. Add system property support in
ServerConstantsorIdentityServeropenidm.context.path/openidm)/and does not end with/1.2. Refactor
ServletComponent.javaFile:
openidm-api-servlet/src/main/java/org/forgerock/openidm/servlet/internal/ServletComponent.javaprivate static final String SERVLET_ALIAS = "/openidm";with a dynamic lookup:activate()instead of the constant.1.3. Refactor
ServletRegistrationSingleton.javaFile:
openidm-servlet-registrator/src/main/java/org/forgerock/openidm/servletregistration/impl/ServletRegistrationSingleton.javaDEFAULT_SERVLET_URL_PATTERNS = new String[] { "/openidm/*", "/selfservice/*" }to use the configurable context path:1.4. Refactor
RemoteCommandScope.javaFile:
openidm-shell/src/main/java/org/forgerock/openidm/shell/impl/RemoteCommandScope.javaIDM_URL_DEFAULT = "http://localhost:8080/openidm/"to use the system property.1.5. Add the property to default
system.properties/boot.propertiesFile:
openidm-zip/src/main/resources/conf/system.properties(or equivalent)openidm.context.path=/openidm2. Frontend (JavaScript UI — openidm-ui)
2.1. Expose context path as a global constant
Constants.jsor a new config module) that the UI reads. The backend should expose the configured context path, for example via an initial config endpoint or by injecting it into the HTML page template.contextPathfield to the existingConstantsobject that defaults to"/openidm"and can be overridden.2.2. Refactor all UI delegate files
Replace all hardcoded
"/openidm"and"/openidm/..."references with the configurable constant. Key files include (but are not limited to):openidm-ui-admin delegates:
ReconDelegate.js—serviceUrl: "/openidm/recon/","/openidm/audit/recon","/openidm/" + link.targetObjectIdSchedulerDelegate.js—constants.host + "/openidm/scheduler/job"ExternalAccessDelegate.js—constants.host + "/openidm/endpoint/oauthproxy",constants.host + "/openidm/external/rest"ClusterDelegate.js—constants.host + "/openidm"WorkflowDelegate.js—constants.host + "/openidm/workflow/processdefinition"ScriptDelegate.js—constants.host + "/openidm/script"ConnectorDelegate.js— uses"/openidm/system"AuditDelegate.js— uses"/openidm/audit/"MaintenanceDelegate.js— uses"/openidm/maintenance"openidm-ui-admin views/models:
ProcessInstanceView.js—url: "/openidm/workflow/processinstance","/openidm/workflow/processdefinition","/openidm/managed/user","/openidm/repo/internal/user","/openidm/workflow/processinstance/","/openidm/workflow/processdefinition/"ProcessDefinitionView.js—url: "/openidm/workflow/processdefinition","/openidm/workflow/processdefinition/"AdminValidators.js—if (v === "/openidm" || v === "/admin" || v === "/system")SettingsView.js—Constants.host + "/openidm/maintenance"openidm-ui-common delegates:
SystemHealthDelegate.js—constants.host + "/openidm/health"SocialDelegate.js—Constants.host + "/openidm/identityProviders",serviceUrl: "/openidm/authentication"SearchDelegate.js—constants.host + "/openidm"InternalUserDelegate.js—constants.host + "/openidm/repo/internal/user"ConfigDelegate.js— likely uses"/openidm/config"ResourceDelegate.js— likely uses"/openidm/"**Pattern...
This pull request was created from Copilot chat.