-
Type:
Suggestion
-
Resolution: Unresolved
-
None
-
Component/s: User - Global / Space Permissions
-
None
-
0
-
4
Background
At the moment, if a space has permissions for 10 different groups, and Confluence needs to check is user has an access to the space, it call this method 10 times:
crowdService.isUserMemberOfGroup(userName, groupName)
If there are a plenty of groups, each call would take some time, and users will notice the slowness of the system.
Possible solutions
Solution 1. We need a method in Crowd like:
crowdService.isUserMemberOfAnyGroup(userName, groupNameList)
It would improve performance, but it requires to change Crowd API.
Solution 2. Retrieve all user groups only once
Another way (without modifying Crowd) is to retrieve all user’s groups first (Crowd allows to do this). And then check check user's groups against space groups without calling Crowd again.
The only problem could be if a user is a part of thousands of groups, but, fortunately, the result will be cached and used for any other space.
Here is the relevant stack-trace:
java.lang.Thread.State: RUNNABLE at org.hibernate.event.internal.ProxyVisitor.processEntity(ProxyVisitor.java:32) at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:107) at org.hibernate.event.internal.WrapVisitor.processValue(WrapVisitor.java:108) at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59) at org.hibernate.event.internal.DefaultFlushEntityEventListener.wrapCollections(DefaultFlushEntityEventListener.java:203) at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:140) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85) at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:44) at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1389) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1474) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1441) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1410) at com.atlassian.crowd.embedded.hibernate2.HibernateSearch.doInHibernate(HibernateSearch.java:112) at com.atlassian.crowd.embedded.hibernate2.HibernateSearch.doInHibernate(HibernateSearch.java:81) at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:385) at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:351) at com.atlassian.crowd.embedded.hibernate2.HibernateMembershipDao.search(HibernateMembershipDao.java:151) at com.atlassian.confluence.user.crowd.CachedCrowdMembershipDao.lambda$childGroupSearch$2(CachedCrowdMembershipDao.java:154) at com.atlassian.confluence.user.crowd.CachedCrowdMembershipDao$$Lambda$1496/0x000000080218d840.get(Unknown Source) at com.atlassian.confluence.user.crowd.DefaultGroupMembershipCache.lambda$getGroupsForGroup$0(DefaultGroupMembershipCache.java:69) at com.atlassian.confluence.user.crowd.DefaultGroupMembershipCache$$Lambda$1498/0x000000080218ec40.get(Unknown Source) at com.atlassian.confluence.cache.CacheOperations.lambda$get$0(CacheOperations.java:172) at com.atlassian.confluence.cache.CacheOperations$$Lambda$1441/0x0000000802017040.apply(Unknown Source) at java.util.HashMap.computeIfAbsent(java.base@11.0.7/Unknown Source) at com.atlassian.confluence.cache.CacheOperations.get(CacheOperations.java:172) at com.atlassian.confluence.cache.DeferredOperationsCache.getOrLoad(DeferredOperationsCache.java:93) at com.atlassian.confluence.cache.DeferredOperationsCache.get(DeferredOperationsCache.java:57) at com.atlassian.confluence.cache.TransactionalCacheFactory$TransactionalCache.get(TransactionalCacheFactory.java:343) at com.atlassian.confluence.impl.cache.tx.TransactionAwareCache$1.get(TransactionAwareCache.java:43) at com.atlassian.confluence.user.crowd.DefaultGroupMembershipCache.getGroupsForGroup(DefaultGroupMembershipCache.java:67) at com.atlassian.confluence.user.crowd.CachedCrowdMembershipDao.childGroupSearch(CachedCrowdMembershipDao.java:153) at com.atlassian.confluence.user.crowd.CachedCrowdMembershipDao.search(CachedCrowdMembershipDao.java:139) at jdk.internal.reflect.GeneratedMethodAccessor454.invoke(Unknown Source) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.7/Unknown Source) at java.lang.reflect.Method.invoke(java.base@11.0.7/Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:16) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$672/0x0000000800bcf840.proceedWithInvocation(Unknown Source) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy249.search(Unknown Source) at com.atlassian.crowd.directory.AbstractInternalDirectory.searchGroupRelationships(AbstractInternalDirectory.java:854) at com.atlassian.crowd.directory.AbstractForwardingDirectory.searchGroupRelationships(AbstractForwardingDirectory.java:234) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.searchDirectGroupRelationships(RemoteDirectorySearcher.java:71) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserIndirectGroupMember(RemoteDirectorySearcher.java:111) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserNestedGroupMember(RemoteDirectorySearcher.java:106) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserIndirectGroupMember(RemoteDirectorySearcher.java:118) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserNestedGroupMember(RemoteDirectorySearcher.java:106) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserIndirectGroupMember(RemoteDirectorySearcher.java:118) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserNestedGroupMember(RemoteDirectorySearcher.java:106) at com.atlassian.crowd.manager.directory.RemoteDirectorySearcher.isUserNestedGroupMember(RemoteDirectorySearcher.java:91) at com.atlassian.crowd.manager.directory.DirectoryManagerGeneric.isUserNestedGroupMember(DirectoryManagerGeneric.java:739) at com.atlassian.crowd.manager.application.ApplicationServiceGeneric$6.fallibleCheckForEntity(ApplicationServiceGeneric.java:1208) at com.atlassian.crowd.manager.application.ApplicationServiceGeneric$DirectoryPredicate.apply(ApplicationServiceGeneric.java:1173) at com.atlassian.crowd.manager.application.ApplicationServiceGeneric$DirectoryPredicate.apply(ApplicationServiceGeneric.java:1169) at com.google.common.collect.Iterators.indexOf(Iterators.java:764) at com.google.common.collect.Iterators.any(Iterators.java:663) at com.google.common.collect.Iterables.any(Iterables.java:608) at com.atlassian.crowd.manager.application.ApplicationServiceGeneric.isUserNestedGroupMember(ApplicationServiceGeneric.java:1686) at com.atlassian.crowd.embedded.core.CrowdServiceImpl.isUserMemberOfGroup(CrowdServiceImpl.java:230) at jdk.internal.reflect.GeneratedMethodAccessor853.invoke(Unknown Source) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.7/Unknown Source) at java.lang.reflect.Method.invoke(java.base@11.0.7/Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:16) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$672/0x0000000800bcf840.proceedWithInvocation(Unknown Source) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy104.isUserMemberOfGroup(Unknown Source) at com.atlassian.confluence.security.AbstractSpacePermissionManager.hasPermissionViaGroups(AbstractSpacePermissionManager.java:387) at com.atlassian.confluence.security.AbstractSpacePermissionManager.hasPermissionNoExemptions(AbstractSpacePermissionManager.java:177) at com.atlassian.confluence.security.CachingSpacePermissionManager.hasPermissionNoExemptions(CachingSpacePermissionManager.java:252) at com.atlassian.confluence.impl.security.recovery.RecoveryAwareCachingSpacePermissionManager.hasPermissionNoExemptions(RecoveryAwareCachingSpacePermissionManager.java:91) at jdk.internal.reflect.GeneratedMethodAccessor1378.invoke(Unknown Source) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.7/Unknown Source) at java.lang.reflect.Method.invoke(java.base@11.0.7/Unknown Source) at com.atlassian.confluence.impl.security.SpacePermissionManagerFactory.lambda$new$0(SpacePermissionManagerFactory.java:68) at com.atlassian.confluence.impl.security.SpacePermissionManagerFactory$$Lambda$457/0x0000000800964c40.invoke(Unknown Source) at com.sun.proxy.$Proxy108.hasPermissionNoExemptions(Unknown Source) at com.atlassian.confluence.security.delegate.AbstractPermissionsDelegate.hasSpaceLevelPermission(AbstractPermissionsDelegate.java:17) at com.atlassian.confluence.security.delegate.PagePermissionsDelegate.canEdit(PagePermissionsDelegate.java:30) at com.atlassian.confluence.security.delegate.PagePermissionsDelegate.canEdit(PagePermissionsDelegate.java:13) at com.atlassian.confluence.security.delegate.TargetToLatestVersionDecorator.canEdit(TargetToLatestVersionDecorator.java:34) at com.atlassian.confluence.security.delegate.SharedAccessInterceptor$$Lambda$2664/0x0000000802fe9040.test(Unknown Source) at com.atlassian.confluence.security.delegate.SharedAccessInterceptor.checkAccess(SharedAccessInterceptor.java:87) at com.atlassian.confluence.security.delegate.SharedAccessInterceptor.canEdit(SharedAccessInterceptor.java:35) at com.atlassian.confluence.security.Permission$2.checkAgainst(Permission.java:29) at com.atlassian.confluence.security.DefaultPermissionManager.hasPermissionNoExemptions(DefaultPermissionManager.java:100) at jdk.internal.reflect.GeneratedMethodAccessor1377.invoke(Unknown Source) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.7/Unknown Source) at java.lang.reflect.Method.invoke(java.base@11.0.7/Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:16) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$672/0x0000000800bcf840.proceedWithInvocation(Unknown Source) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy115.hasPermissionNoExemptions(Unknown Source) at com.atlassian.confluence.plugin.descriptor.web.conditions.PagePermissionCondition.shouldDisplay(PagePermissionCondition.java:19) at com.atlassian.confluence.plugin.descriptor.web.conditions.BaseConfluenceCondition.shouldDisplay(BaseConfluenceCondition.java:33) at com.atlassian.plugin.web.conditions.AndCompositeCondition.shouldDisplay(AndCompositeCondition.java:22) at com.atlassian.plugin.web.DefaultWebInterfaceManager.filterFragmentsByCondition(DefaultWebInterfaceManager.java:160) at com.atlassian.plugin.web.DefaultWebInterfaceManager.getDisplayableItems(DefaultWebInterfaceManager.java:113) at com.atlassian.confluence.plugin.descriptor.web.ConfluenceWebInterfaceManager.getDisplayableItems(ConfluenceWebInterfaceManager.java:78)
- mentioned in
-
Page Loading...