Organization configuration via URL or local file#950
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds “Organization Configuration” support to the AppMap JetBrains plugin, allowing enterprise deployment settings to be applied at runtime from either a URL (including APPMAP_CONFIG_URL) or a one-shot local file, and surfaces that functionality via an action, settings UI, and the sign-in webview.
Changes:
- Introduces an
EnterpriseConfigService+ non-roaming cache to fetch/apply org config asynchronously and persist the last good config. - Adds UI/action entry points (Tools menu, settings page, sign-in screen) to apply/change/clear org config and show status.
- Updates deployment/telemetry plumbing to support nullable “auto-update tools” and hot-reload telemetry routing when org config changes.
Reviewed changes
Copilot reviewed 3 out of 120 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents runtime org config and manifest URL overrides. |
| plugin-core/src/test/java/appland/utils/AppMapFileChoosersTest.java | Adds tests for background initial-directory resolution for file choosers. |
| plugin-core/src/test/java/appland/deployment/AppMapDeploymentSettingsTest.java | Updates tests for nullable autoUpdateTools semantics. |
| plugin-core/src/test/java/appland/deployment/AppMapDeploymentSettingsServiceTest.java | Updates default auto-update expectation for nullable settings. |
| plugin-core/src/main/resources/META-INF/appmap-core.xml | Registers enterprise config services/startup activity and new action. |
| plugin-core/src/main/resources/messages/appland.properties | Adds UI strings for org-config action/settings UI. |
| plugin-core/src/main/kotlin/appland/settings/AppMapProjectSettingsPanel.kt | Adds org-config status/apply/change/clear UI in settings panel. |
| plugin-core/src/main/java/appland/utils/AppMapFileChoosers.java | Adds async file chooser helpers to avoid slow VFS ops on EDT. |
| plugin-core/src/main/java/appland/toolwindow/signInView/SignInViewPanel.java | Adds org-config init data + reactive applied-state updates to sign-in webview. |
| plugin-core/src/main/java/appland/telemetry/TelemetryService.java | Enables telemetry reporter hot-reload on org-config changes. |
| plugin-core/src/main/java/appland/settings/DownloadSettings.java | Treats nullable deployment auto-update as “enabled unless explicitly false”. |
| plugin-core/src/main/java/appland/settings/AutoDownloadSettingsListener.java | Refreshes downloads when enterprise deployment settings change. |
| plugin-core/src/main/java/appland/settings/AppMapSettingsReloadProjectListener.java | Restarts JSON-RPC server when effective telemetry settings change. |
| plugin-core/src/main/java/appland/settings/AppMapSettingsListener.java | Adds new settings bus events for org config + telemetry changes. |
| plugin-core/src/main/java/appland/settings/AppMapProjectConfigurable.java | Reloads settings UI live when org/deployment settings change. |
| plugin-core/src/main/java/appland/settings/AppMapApplicationSettings.java | Persists org-config URL + applied timestamp; publishes URL changes. |
| plugin-core/src/main/java/appland/enterpriseConfig/EnterpriseConfigStartupActivity.java | Eager background org-config fetch at startup (non-test). |
| plugin-core/src/main/java/appland/enterpriseConfig/EnterpriseConfigSettingsListener.java | Triggers async apply when config URL changes. |
| plugin-core/src/main/java/appland/enterpriseConfig/EnterpriseConfigService.java | Core org-config fetch/apply/clear/cache + override superseding + telemetry reload. |
| plugin-core/src/main/java/appland/enterpriseConfig/EnterpriseConfigCacheService.java | Non-roaming persistence for cached org-config JSON (token may be present). |
| plugin-core/src/main/java/appland/deployment/AppMapDeploymentSettingsService.java | Merges enterprise settings over bundled defaults on read path. |
| plugin-core/src/main/java/appland/deployment/AppMapDeploymentSettings.java | Makes autoUpdateTools nullable to distinguish “unset” vs explicit value. |
| plugin-core/src/main/java/appland/actions/SetConfigurationUrlAction.java | Adds action to apply org config via URL or local file. |
| plugin-core/src/main/java/appland/actions/PluginStatus.java | Includes org-config source + redacted contents in plugin status report. |
| plugin-core/src/main/java/appland/actions/ChooseAndAddNavieContextFilesAction.java | Switches to async chooser helper for pinned files selection. |
| ORGANIZATION_CONFIGURATION.md | New doc explaining schema, application methods, precedence, and failure behavior. |
| appland-webview/yarn.lock | Updates @appland/components dependency lock to ^4.49.0. |
| appland-webview/signin.js | Adds webview event to request org-config apply and react to applied state. |
| appland-webview/package.json | Bumps @appland/components to ^4.49.0. |
| appland-webview/dist/timeline-definition-faaaa080-FCQT3WAD.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/stateDiagram-v2-c2b004d7-CUVNE3XY.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/stateDiagram-1ecb1508-7NKRNZHU.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/signin.js.map | Rebuilt webview dist sourcemap (org-config UI hook). |
| appland-webview/dist/signin.js | Rebuilt webview dist bundle (org-config UI hook). |
| appland-webview/dist/review.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/review.js | Rebuilt webview dist bundle (dependency bump). |
| appland-webview/dist/pieDiagram-a8764435-YUCDHKSQ.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/navie.js | Rebuilt webview dist bundle (dependency bump). |
| appland-webview/dist/install-guide.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/install-guide.js | Rebuilt webview dist bundle (dependency bump). |
| appland-webview/dist/infoDiagram-8eee0895-AM7FTXMF.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/flowDiagram-v2-4f6560a1-UTQCF3NU.js | Removed old flow diagram dist asset (rebuilt/renamed output). |
| appland-webview/dist/flowDiagram-v2-4f6560a1-R6D7EA5S.js.map | Adds rebuilt flow diagram sourcemap. |
| appland-webview/dist/flowDiagram-v2-4f6560a1-R6D7EA5S.js | Adds rebuilt flow diagram dist asset. |
| appland-webview/dist/findings.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/findings.js | Rebuilt webview dist bundle (dependency bump). |
| appland-webview/dist/classDiagram-v2-2358418a-M6GJQI5I.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/classDiagram-beda092f-5UIOK7GK.js | Rebuilt webview dist asset (dependency bump). |
| appland-webview/dist/chunk-TAOBJH36.js | Rebuilt webview dist chunk (dependency bump). |
| appland-webview/dist/chunk-LUO6KAAB.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/chunk-LUO6KAAB.js | Rebuilt webview dist chunk (dependency bump). |
| appland-webview/dist/chunk-2HYH4KIK.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/chunk-2HYH4KIK.js | Rebuilt webview dist chunk (dependency bump). |
| appland-webview/dist/appmap.js.map | Rebuilt webview dist sourcemap (dependency bump). |
| appland-webview/dist/appmap.js | Rebuilt webview dist bundle (dependency bump). |
| .editorconfig | Keeps blank lines in .properties files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7b7469e to
b098c97
Compare
7ee8608 to
38c6d44
Compare
…file Add EnterpriseConfigService that fetches organization deployment settings from a configured URL (or APPMAP_CONFIG_URL env var) or a local file, caches the last successful result, and merges enterprise settings over bundled defaults. Wires the "Apply Organization Configuration" action, sign-in view affordances, and settings panel fields. Assisted-by: Claude:claude-opus-4-8
Preserves the blank-line separation before the enterprise-config strings. Assisted-by: Claude:claude-opus-4-8
Adds the signin.js counterpart for the organization-configuration sign-in affordances (enableOrgConfig / apply-org-config) and includes the regenerated webview dist bundle. Assisted-by: Claude:claude-opus-4-8
The restart notification fired unconditionally whenever org config was applied, even when the config had no telemetry section. Rebuild the telemetry reporter from the current deployment settings when the org configuration changes, so telemetry routing updates without an IDE restart. Assisted-by: Claude:claude-opus-4-8
When the user changes the configuration URL to one that is unreachable or returns invalid content, the previously applied organization config used to silently linger. Treat an interactive apply failure (and empty/invalid JSON) as a clear-and-notify: drop the in-memory settings and cache and warn the user. Startup/lazy fetches stay non-interactive and keep the cached settings as an offline fallback instead of wiping a known-good config on a transient failure. Assisted-by: Claude:claude-opus-4-8
Applying an organization config previously had no visible effect when the user had already set the same setting, because user overrides always win at runtime. On apply, clear the user override for each setting the org config specifies so it actually takes effect (the user can override again afterward). A new URL or local-file apply supersedes every specified setting; a repeat fetch from the same URL only supersedes settings whose org value changed since the last fetch. Each superseded override is logged. Assisted-by: Claude:claude-opus-4-8
Reading deployment settings used to lazily trigger and block on the org-config fetch, which logged a SEVERE "wait requested on EDT" error whenever the UI read settings (e.g. on Apply). Fetch eagerly at startup instead, and make the read path only restore the persisted cache — cheap, thread-safe, and EDT-safe. Because the fetch is now asynchronous, AutoDownloadSettingsListener also reacts to enterpriseDeploymentSettingsChanged so a freshly-applied org config still re-evaluates downloads without a restart. Assisted-by: Claude:claude-opus-4-8
The settings page only loaded values when first opened, so applying a config URL (whose fetch completes asynchronously) left stale values shown until the page was reopened. Subscribe to settings changes while the page is open and reload it when the organization deployment settings or auto-update flag change. Assisted-by: Claude:claude-opus-4-8
Add a settings-page row that appears when an organization configuration is active, showing its source (URL / local file / environment) and when it was applied, with a Clear button that removes the URL, cache, applied timestamp and in-memory settings. Plugin status now also reports whether an org config is active and where it came from. Assisted-by: Claude:claude-opus-4-8
Plugin status is a debugging aid, so include the full raw JSON contents of the currently-applied organization configuration alongside its source. Assisted-by: Claude:claude-opus-4-8
- Reconfigure telemetry (reload reporter + restart the JSON-RPC server, which receives telemetry settings via its environment) only when the effective telemetry settings actually change, via a new telemetrySettingsChanged signal. Restarting is relatively expensive, so it must not fire on unrelated changes. - Switching config source (local file, or Clear) now clears the previous URL non-notifying, avoiding a redundant second apply pipeline that produced the duplicate "reloaded telemetry reporter" log lines. - Show an informational notification when an org config is applied interactively (not on startup refresh). - Tests for the URL-clearing, clear-all-state, and telemetry-change-only-on-change behavior; rebuild the shared telemetry reporter in teardown to avoid leaking an always-enabled Splunk reporter into other tests. Assisted-by: Claude:claude-opus-4-8
The settings page no longer has a raw Organization Config URL text field. Instead it shows an "Apply Organization Configuration…" button when no config is applied, and the active-config indicator with "Change…" and "Clear" buttons when one is. All three buttons drive the existing apply/clear flows, keeping URL/local-file handling in one place (the action) rather than split across the settings form. Assisted-by: Claude:claude-opus-4-8
…loyers Documents the runtime organization configuration: the JSON schema, the three ways to apply it (APPMAP_CONFIG_URL env var, in-IDE URL, local file), the bundled-vs-organization-vs-user precedence and override-on-apply behavior, offline/failure handling, clearing, verification via Plugin Status Report, and a snippet deployers can adapt to guide their users. Linked from the README. Assisted-by: Claude:claude-opus-4-8
Addresses findings from a review of the feature branch: Security: - Redact the Splunk HEC token from getAppliedConfigJson(), so it can't leak via the Plugin Status Report (which users paste into bug reports). The public CA cert and other fields are kept for debuggability. - Move the cached org-config JSON (which can contain the token) out of the roaming application settings into a new non-roaming EnterpriseConfigCacheService (RoamingType.DISABLED), so the token is no longer synced to JetBrains cloud / other machines. It is still persisted locally as an offline fallback. Concurrency: - Replace the tangled fetch-future machinery (AtomicReference<CompletableFuture>, getOrStartFetchFuture, IS_FETCHING) — which could return null (NPE), abandon futures, spawn duplicate fetches, and log a spurious EDT "logic error" — with a generation counter plus a lock. A slow in-flight fetch now checks it hasn't been superseded before mutating, and all apply/clear critical sections are serialized, so a fetch can no longer clobber a newer Clear or local-file apply. - awaitInitialFetchIfConfigured now fetches synchronously on its background thread and only warns (not errors) if mis-called on the EDT. Also fixes the stale "never cleared" doc on orgConfigAppliedAt. Adds tests for token redaction, same-URL-only-changed-keys supersession, and interactive-failure clearing. Assisted-by: Claude:claude-opus-4-8
If createComponent() is called again before disposeUIResources(), disconnect the previous message-bus connection first so the old listener isn't leaked. Assisted-by: Claude:claude-opus-4-8
FileChooser.chooseFile/chooseFiles resolve a path via VFS on the EDT (their "restore last selection" logic), which trips the platform's slow-operations assertion. Add appland.utils.AppMapFileChoosers: it resolves a sensible initial directory off the EDT (last-opened -> project root -> user home) and opens the chooser with it pre-selected, delivering the result via callback. Use it for the organization-config local-file picker and the Navie pinned-files picker. Public API only (no deprecated allowSlowOperations, no @internal knownIssue). The assertion is a dev/internal-mode diagnostic not shown to released users, but this keeps dev logs clean and restores the "reopen the last folder" behavior. Assisted-by: Claude:claude-opus-4-8
The apply-org-config handler read isApplied() immediately after showPicker() and posted it back, but applying is asynchronous (URL fetch, and the local-file chooser now opens via invokeLater), so the read happened before the apply landed — the local-file case never updated the webview. The IDE side now subscribes to enterpriseDeploymentSettingsChanged and pushes the applied state when it actually changes; the webview (signin.js) registers the apply-org-config handler with `on` (not `once`) at init so it reacts to those pushes regardless of where the config was applied. (isApplied() still treats a configured URL as applied, by design.) Assisted-by: Claude:claude-opus-4-8
Review follow-ups in EnterpriseConfigService: - Convert file:// org-config URLs to a path via proper URI parsing with a raw-path fallback: handles file:/// , escaped characters, and UNC, while still accepting the "file://" + raw OS path form (incl. Windows file://C:\...). An unparseable file URL is treated as a fetch failure. - Mask URL credentials (userinfo) in logs, the status report, and notifications so they can't leak. - getConfigSourceDescription reports "local file" when a local-file snapshot is the active config even if APPMAP_CONFIG_URL is set (the env URL only re-applies on the next startup, so the session's effective source is the local file). Assisted-by: Claude:claude-opus-4-8
This allows all the test suites to run to completion so there are fewer feedback cycles (hopefully).
38c6d44 to
37530a9
Compare
The previously used version is no longer publicly available in the Maven repository. This change updates it to the newest available version.
d5aae68 to
1dda24b
Compare
|
🎉 This PR is included in version 0.85.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The organization configuration can now be applied from either a URL or local file. The functionality can be accessed through an action, menu item, from the settings dialog or the login screen.