Skip to content

Commit

Permalink
Grails 7: Update usercache page to display statistics for a JSR-107 C…
Browse files Browse the repository at this point in the history
…ache
  • Loading branch information
bkoehm committed Dec 20, 2024
1 parent 5654725 commit 71e7d04
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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() {
Expand Down
52 changes: 21 additions & 31 deletions examples/simple/grails-app/views/securityInfo/usercache.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,55 @@
<p/>
<g:message code='spring.security.ui.info.usercache.classname' args='[cache.getClass().name]'/>
<s2ui:securityInfoTable type='usercache' headerCodes='attribute,value'>
<tr class='even'>
<td><g:message code='spring.security.ui.info.usercache.label.size'/></td>
<td>${cache.size}</td>
</tr>
<tr class='odd'>
<td><g:message code='spring.security.ui.info.usercache.label.status'/></td>
<td>${cache.status}</td>
</tr>
<tr class='even'>
<td><g:message code='spring.security.ui.info.usercache.label.name'/></td>
<td>${cache.name}</td>
</tr>
<tr class='odd'>
<td><g:message code='spring.security.ui.info.usercache.label.guid'/></td>
<td>${cache.guid}</td>
</tr>
<tr class='even'>
<td colspan='2'>
<s2ui:securityInfoTable type='usercache.statistics' headerCodes='attribute,value'>
<s2ui:securityInfoTable type='usercache.statistics' headerCodes='attribute,value'>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheHits'/></td>
<td>${cache.statistics.cacheHitCount()}</td>
<td>${cache.statisticsMBean.cacheHits}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.memoryHits'/></td>
<td>${cache.statistics.localHeapHitCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheHitPercentage'/></td>
<td>${cache.statisticsMBean.cacheHitPercentage}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.diskHits'/></td>
<td>${cache.statistics.localDiskHitCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMisses'/></td>
<td>${cache.statisticsMBean.cacheMisses}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMisses'/></td>
<td>${cache.statistics.cacheMissCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMissPercentage'/></td>
<td>${cache.statisticsMBean.cacheMissPercentage}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.objectCount'/></td>
<td>${cache.statistics.size}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheGets'/></td>
<td>${cache.statisticsMBean.cacheGets}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.memoryObjectCount'/></td>
<td>${cache.statistics.localHeapSize}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cachePuts'/></td>
<td>${cache.statisticsMBean.cachePuts}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.diskObjectCount'/></td>
<td>${cache.statistics.localDiskSize}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheRemovals'/></td>
<td>${cache.statisticsMBean.cacheRemovals}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.evictionCount'/></td>
<td>${cache.statistics.cacheEvictedCount()}</td>
<td>${cache.statisticsMBean.cacheEvictions}</td>
</tr>
</s2ui:securityInfoTable>
</s2ui:securityInfoTable>
</td>
</tr>
<tr>
<td colspan='2'>
<s2ui:securityInfoTable type='usercache.cachedUsers' items='${cache.keys}' headerCodes='username,user' captionArgs='[cache.size]'>
<td>${it}</td>
<td>${cache.get(it)?.value}</td>
<s2ui:securityInfoTable type='usercache.cachedUsers' items='${cache.iterator()}' headerCodes='username,user'>
<g:if test="${it}">
<td>${it.key}</td>
<td>${it.value}</td>
</g:if>
</s2ui:securityInfoTable>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class SecurityInfoController {
}

def usercache() {
[cache: conf.cacheUsers ? userCache.cache : false]
[cache: conf.cacheUsers ? userCache.cache.nativeCache : false]
}

def filterChains() {
Expand Down
15 changes: 6 additions & 9 deletions plugin/grails-app/i18n/messages.spring-security-ui.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
52 changes: 21 additions & 31 deletions plugin/grails-app/views/securityInfo/usercache.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,55 @@
<p/>
<g:message code='spring.security.ui.info.usercache.classname' args='[cache.getClass().name]'/>
<s2ui:securityInfoTable type='usercache' headerCodes='attribute,value'>
<tr class='even'>
<td><g:message code='spring.security.ui.info.usercache.label.size'/></td>
<td>${cache.size}</td>
</tr>
<tr class='odd'>
<td><g:message code='spring.security.ui.info.usercache.label.status'/></td>
<td>${cache.status}</td>
</tr>
<tr class='even'>
<td><g:message code='spring.security.ui.info.usercache.label.name'/></td>
<td>${cache.name}</td>
</tr>
<tr class='odd'>
<td><g:message code='spring.security.ui.info.usercache.label.guid'/></td>
<td>${cache.guid}</td>
</tr>
<tr class='even'>
<td colspan='2'>
<s2ui:securityInfoTable type='usercache.statistics' headerCodes='attribute,value'>
<s2ui:securityInfoTable type='usercache.statistics' headerCodes='attribute,value'>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheHits'/></td>
<td>${cache.statistics.cacheHitCount()}</td>
<td>${cache.statisticsMBean.cacheHits}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.memoryHits'/></td>
<td>${cache.statistics.localHeapHitCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheHitPercentage'/></td>
<td>${cache.statisticsMBean.cacheHitPercentage}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.diskHits'/></td>
<td>${cache.statistics.localDiskHitCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMisses'/></td>
<td>${cache.statisticsMBean.cacheMisses}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMisses'/></td>
<td>${cache.statistics.cacheMissCount()}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheMissPercentage'/></td>
<td>${cache.statisticsMBean.cacheMissPercentage}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.objectCount'/></td>
<td>${cache.statistics.size}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheGets'/></td>
<td>${cache.statisticsMBean.cacheGets}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.memoryObjectCount'/></td>
<td>${cache.statistics.localHeapSize}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cachePuts'/></td>
<td>${cache.statisticsMBean.cachePuts}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.diskObjectCount'/></td>
<td>${cache.statistics.localDiskSize}</td>
<td><g:message code='spring.security.ui.info.usercache.label.stats.cacheRemovals'/></td>
<td>${cache.statisticsMBean.cacheRemovals}</td>
</tr>
<tr>
<td><g:message code='spring.security.ui.info.usercache.label.stats.evictionCount'/></td>
<td>${cache.statistics.cacheEvictedCount()}</td>
<td>${cache.statisticsMBean.cacheEvictions}</td>
</tr>
</s2ui:securityInfoTable>
</s2ui:securityInfoTable>
</td>
</tr>
<tr>
<td colspan='2'>
<s2ui:securityInfoTable type='usercache.cachedUsers' items='${cache.keys}' headerCodes='username,user' captionArgs='[cache.size]'>
<td>${it}</td>
<td>${cache.get(it)?.value}</td>
<s2ui:securityInfoTable type='usercache.cachedUsers' items='${cache.iterator()}' headerCodes='username,user'>
<g:if test="${it}">
<td>${it.key}</td>
<td>${it.value}</td>
</g:if>
</s2ui:securityInfoTable>
</td>
</tr>
Expand Down

0 comments on commit 71e7d04

Please sign in to comment.