From 71e7d0492b70417a4b3ea3356dfc8ccf8c3cc11f Mon Sep 17 00:00:00 2001
From: Brian Koehmstedt <1261658+bkoehm@users.noreply.github.com>
Date: Fri, 20 Dec 2024 10:05:03 -0800
Subject: [PATCH] Grails 7: Update usercache page to display statistics for a
JSR-107 Cache
---
.../spec/ExtendedSecurityInfoSpec.groovy | 23 +++++++-
.../views/securityInfo/usercache.gsp | 52 ++++++++-----------
.../spec/DefaultSecurityInfoSpec.groovy | 25 +++++++--
.../ui/SecurityInfoController.groovy | 2 +-
.../messages.spring-security-ui.properties | 15 +++---
.../views/securityInfo/usercache.gsp | 52 ++++++++-----------
6 files changed, 92 insertions(+), 77 deletions(-)
diff --git a/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy b/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy
index a398e660..a9f82873 100644
--- a/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy
+++ b/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy
@@ -1,10 +1,14 @@
package spec
import grails.testing.mixin.integration.Integration
+import org.springframework.security.core.userdetails.User
+import org.springframework.security.core.userdetails.UserCache
@Integration
class ExtendedSecurityInfoSpec extends AbstractSecuritySpec {
+ UserCache userCache
+
void testConfig() {
when:
go 'securityInfo/config'
@@ -37,12 +41,27 @@ class ExtendedSecurityInfoSpec extends AbstractSecuritySpec {
}
void testUsercache() {
+ given:
+ userCache.putUserInCache(new User('testuser', 'pw', []))
+
+ when:
+ go 'securityInfo/usercache'
+
+ then:
+ assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache'
+ assertContentContains 'testuser'
+
+ cleanup:
+ userCache.removeUserFromCache('testuser')
+ }
+
+ void testEmptyUsercache() {
when:
go 'securityInfo/usercache'
then:
- assertContentContains 'UserCache class: net.sf.ehcache.Cache'
- assertContentContains 'Memory Store Object Count 0'
+ assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache'
+ assertContentDoesNotContain'testuser'
}
void testFilterChains() {
diff --git a/examples/simple/grails-app/views/securityInfo/usercache.gsp b/examples/simple/grails-app/views/securityInfo/usercache.gsp
index 30366330..b7c21879 100644
--- a/examples/simple/grails-app/views/securityInfo/usercache.gsp
+++ b/examples/simple/grails-app/views/securityInfo/usercache.gsp
@@ -8,65 +8,55 @@
-
- |
- ${cache.size} |
-
-
- |
- ${cache.status} |
-
|
${cache.name} |
-
- |
- ${cache.guid} |
-
-
+
|
- ${cache.statistics.cacheHitCount()} |
+ ${cache.statisticsMBean.cacheHits} |
- |
- ${cache.statistics.localHeapHitCount()} |
+ |
+ ${cache.statisticsMBean.cacheHitPercentage} |
- |
- ${cache.statistics.localDiskHitCount()} |
+ |
+ ${cache.statisticsMBean.cacheMisses} |
- |
- ${cache.statistics.cacheMissCount()} |
+ |
+ ${cache.statisticsMBean.cacheMissPercentage} |
- |
- ${cache.statistics.size} |
+ |
+ ${cache.statisticsMBean.cacheGets} |
- |
- ${cache.statistics.localHeapSize} |
+ |
+ ${cache.statisticsMBean.cachePuts} |
- |
- ${cache.statistics.localDiskSize} |
+ |
+ ${cache.statisticsMBean.cacheRemovals} |
|
- ${cache.statistics.cacheEvictedCount()} |
+ ${cache.statisticsMBean.cacheEvictions} |
-
+
|
-
- ${it} |
- ${cache.get(it)?.value} |
+
+
+ ${it.key} |
+ ${it.value} |
+
|
diff --git a/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy b/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy
index 8ebe889b..dfff080b 100644
--- a/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy
+++ b/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy
@@ -1,10 +1,14 @@
package spec
import grails.testing.mixin.integration.Integration
+import org.springframework.security.core.userdetails.User
+import org.springframework.security.core.userdetails.UserCache
@Integration
class DefaultSecurityInfoSpec extends AbstractSecuritySpec {
+ UserCache userCache
+
void testConfig() {
when:
go 'securityInfo/config'
@@ -32,17 +36,32 @@ class DefaultSecurityInfoSpec extends AbstractSecuritySpec {
go 'securityInfo/currentAuth'
then:
- assertContentContains 'org.springframework.security.web.authentication.WebAuthenticationDetails'
+ assertContentContains 'Details WebAuthenticationDetails'
assertContentContains '__grails.anonymous.user__'
}
void testUsercache() {
+ given:
+ userCache.putUserInCache(new User('testuser', 'pw', []))
+
+ when:
+ go 'securityInfo/usercache'
+
+ then:
+ assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache'
+ assertContentContains 'testuser'
+
+ cleanup:
+ userCache.removeUserFromCache('testuser')
+ }
+
+ void testEmptyUsercache() {
when:
go 'securityInfo/usercache'
then:
- assertContentContains 'UserCache class: net.sf.ehcache.Cache'
- assertContentContains 'Memory Store Object Count 0'
+ assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache'
+ assertContentDoesNotContain'testuser'
}
void testFilterChains() {
diff --git a/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy b/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy
index 6291e5d5..f81dcfad 100644
--- a/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy
+++ b/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy
@@ -52,7 +52,7 @@ class SecurityInfoController {
}
def usercache() {
- [cache: conf.cacheUsers ? userCache.cache : false]
+ [cache: conf.cacheUsers ? userCache.cache.nativeCache : false]
}
def filterChains() {
diff --git a/plugin/grails-app/i18n/messages.spring-security-ui.properties b/plugin/grails-app/i18n/messages.spring-security-ui.properties
index bf496f22..d4daf369 100644
--- a/plugin/grails-app/i18n/messages.spring-security-ui.properties
+++ b/plugin/grails-app/i18n/messages.spring-security-ui.properties
@@ -37,7 +37,7 @@ spring.security.ui.menu.securityInfo.mappings Mappings
spring.security.ui.menu.securityInfo.providers Authentication Providers
spring.security.ui.menu.securityInfo.secureChannel Secure Channel Definition
spring.security.ui.menu.securityInfo.usercache User Cache
-spring.security.ui.menu.securityInfo.usercache.cachedUsers {0} Cached User(s)
+spring.security.ui.menu.securityInfo.usercache.cachedUsers Cached User(s)
spring.security.ui.menu.securityInfo.usercache.statistics Statistics
spring.security.ui.menu.securityInfo.voters Voters
spring.security.ui.menu.user Users
@@ -93,18 +93,15 @@ spring.security.ui.info.usercache.classname UserCache class: {0}
spring.security.ui.info.usercache.disabled Not Caching Users
spring.security.ui.info.usercache.header.attribute Attribute
spring.security.ui.info.usercache.header.value Value
-spring.security.ui.info.usercache.label.guid GUID
spring.security.ui.info.usercache.label.name Name
-spring.security.ui.info.usercache.label.size Size
spring.security.ui.info.usercache.label.stats.cacheHits Cache Hits
+spring.security.ui.info.usercache.label.stats.cacheHitPercentage Cache Hit Percentage
spring.security.ui.info.usercache.label.stats.cacheMisses Cache Misses
-spring.security.ui.info.usercache.label.stats.diskHits On-disk Hits
-spring.security.ui.info.usercache.label.stats.diskObjectCount Disk Store Object Count
+spring.security.ui.info.usercache.label.stats.cacheMissPercentage Cache Miss Percentage
+spring.security.ui.info.usercache.label.stats.cacheGets Cache Gets
+spring.security.ui.info.usercache.label.stats.cachePuts Cache Puts
+spring.security.ui.info.usercache.label.stats.cacheRemovals Cache Removals
spring.security.ui.info.usercache.label.stats.evictionCount Eviction Count
-spring.security.ui.info.usercache.label.stats.memoryHits In-memory Hits
-spring.security.ui.info.usercache.label.stats.memoryObjectCount Memory Store Object Count
-spring.security.ui.info.usercache.label.stats.objectCount Object Count
-spring.security.ui.info.usercache.label.status Status
spring.security.ui.info.usercache.statistics.header.attribute Attribute
spring.security.ui.info.usercache.statistics.header.value Value
spring.security.ui.info.voters.header.className Class Name
diff --git a/plugin/grails-app/views/securityInfo/usercache.gsp b/plugin/grails-app/views/securityInfo/usercache.gsp
index 30366330..b7c21879 100644
--- a/plugin/grails-app/views/securityInfo/usercache.gsp
+++ b/plugin/grails-app/views/securityInfo/usercache.gsp
@@ -8,65 +8,55 @@
-
- |
- ${cache.size} |
-
-
- |
- ${cache.status} |
-
|
${cache.name} |
-
- |
- ${cache.guid} |
-
-
+
|
- ${cache.statistics.cacheHitCount()} |
+ ${cache.statisticsMBean.cacheHits} |
- |
- ${cache.statistics.localHeapHitCount()} |
+ |
+ ${cache.statisticsMBean.cacheHitPercentage} |
- |
- ${cache.statistics.localDiskHitCount()} |
+ |
+ ${cache.statisticsMBean.cacheMisses} |
- |
- ${cache.statistics.cacheMissCount()} |
+ |
+ ${cache.statisticsMBean.cacheMissPercentage} |
- |
- ${cache.statistics.size} |
+ |
+ ${cache.statisticsMBean.cacheGets} |
- |
- ${cache.statistics.localHeapSize} |
+ |
+ ${cache.statisticsMBean.cachePuts} |
- |
- ${cache.statistics.localDiskSize} |
+ |
+ ${cache.statisticsMBean.cacheRemovals} |
|
- ${cache.statistics.cacheEvictedCount()} |
+ ${cache.statisticsMBean.cacheEvictions} |
-
+
|
-
- ${it} |
- ${cache.get(it)?.value} |
+
+
+ ${it.key} |
+ ${it.value} |
+
|