fix: end DS activation race that broke system-realm auth at startup (#1882)#44
Merged
Merged
Conversation
GridOpticsServer authenticated the system/manager principal against the Shiro realm set before the system-authenticating realm was registered, so platform startup died nondeterministically with "Realm UnauthTokenBasedRealm was unable to find account data for system" (GridOPTICS/GOSS-GridAPPS-D#1882). The DependencyManager to Declarative Services migration left the realm set populated asynchronously by two racing binders, and the AT_LEAST_ONE guard only ensured some realm was present, not the system realm. Mark SystemBasedRealm with a realm.type=system service property, and add a mandatory target-filtered @reference on it to both the SecurityManager component (Activator, gating service publication) and GridOpticsServer (gating @Activate/broker-connect). Collapse the realm-set write to a single owner: SecurityManagerRealmHandler no longer calls setRealms(), so a partial write can no longer transiently drop the system realm. The filter string is a shared compile-time constant on GossRealm. UnauthTokenBasedRealm returning null for system is intentional and unchanged; the fix is ordering only. No client credential or permission contract changes.
Behavioral tests: system authentication fails when only a non-system realm is wired (reproduces #1882), succeeds once the system realm is in the set, and retains the "*" permission after a later realm binds. Contract tests parse the bnd-emitted OSGI-INF descriptors to assert the realm.type=system property and the (realm.type=system) reference targets are present and that the handler no longer references the SecurityManager. Descriptor tests fail (not skip) when run under Gradle with the bundle artifact absent.
Pre-existing spotlessCheck violation on develop, unrelated to the activation fix but folded in so the branch CI is green. Closes #41.
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.
Problem
The GridAPPS-D develop tag failed to start nondeterministically (machine and startup-path dependent), reported in GRIDAPPSD/GOSS-GridAPPS-D#1882. On the failing path,
goss-core-serverdied during OSGi Declarative Services activation:Root cause
The DependencyManager to Declarative Services migration left the Shiro realm set populated asynchronously by two racing binders.
GridOpticsServer.start()(@activate) opens the broker and immediately authenticatescreateConnection("system", "manager"). TheAT_LEAST_ONEcardinality guard only ensured some realm was bound, not the system-authenticating one. When the broker authenticatedsystembeforeSystemBasedRealmwas in the set, onlyUnauthTokenBasedRealmanswered, returned null (by design), and startup died.Fix
SystemBasedRealmwith arealm.type=systemservice property.@Reference(target="(realm.type=system)")to both the SecurityManager component (Activator, gating service publication) andGridOpticsServer(gating@Activate/broker-connect). Declarative Services now holds activation until the system-authenticating realm is bound.SecurityManagerRealmHandlerno longer callssetRealms(), so a partial write can no longer transiently drop the system realm.GossRealm.UnauthTokenBasedRealmreturning null forsystemis intentional and unchanged. The fix is ordering only: no client credential or permission contract changes.Testing
SystemRealmActivationOrderTest(7 cases): behavioral (system auth fails with only a non-system realm wired, succeeds once the system realm binds,*permission survives a later binding) plus DS-descriptor contract assertions (property/target present, handler no longer references the SecurityManager)../gradlew :pnnl.goss.core:buildis green.Coverage note: true multi-bundle container activation ordering is not unit-testable here (no Pax Exam configured). The tests assert the wiring/auth invariants the container ordering depends on; a live Felix boot on the affected machine confirms end-to-end sequencing.
Reviews
Reviewed for code quality and security (fail-closed confirmed, no fail-open window, no dropped realm).
Related