improve cache invalidation on group events

This commit is contained in:
Sebastian Sdorra
2016-06-26 15:03:28 +02:00
parent 89660e8ac3
commit 9dc1c6fd8e
2 changed files with 83 additions and 37 deletions

View File

@@ -72,6 +72,8 @@ import sonia.scm.util.Util;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import sonia.scm.Filter; import sonia.scm.Filter;
import sonia.scm.group.Group;
import sonia.scm.group.GroupModificationEvent;
import sonia.scm.repository.RepositoryModificationEvent; import sonia.scm.repository.RepositoryModificationEvent;
import sonia.scm.user.UserModificationEvent; import sonia.scm.user.UserModificationEvent;
@@ -162,7 +164,7 @@ public class AuthorizationCollector
if (event instanceof UserModificationEvent) if (event instanceof UserModificationEvent)
{ {
User beforeModification = ((UserModificationEvent) event).getItemBeforeModification(); User beforeModification = ((UserModificationEvent) event).getItemBeforeModification();
if ( shouldCacheBeCleared(user, beforeModification) ) if (shouldCacheBeCleared(user, beforeModification))
{ {
invalidateUserCache(username); invalidateUserCache(username);
} }
@@ -183,7 +185,8 @@ public class AuthorizationCollector
return user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive(); return user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive();
} }
private void invalidateUserCache(final String username){ private void invalidateUserCache(final String username)
{
logger.debug("invalidate cache of user {}, because of a event which could change the permissions", username); logger.debug("invalidate cache of user {}, because of a event which could change the permissions", username);
cache.removeAll(new Filter<CacheKey>() cache.removeAll(new Filter<CacheKey>()
{ {
@@ -279,26 +282,50 @@ public class AuthorizationCollector
} }
/** /**
* Method description * Invalidates the whole cache, if a group has changed. The cache get cleared for one of the following reasons:
* <ul>
* <li>New group created</li>
* <li>Group was removed</li>
* <li>Group members was modified</li>
* </ul>
* *
* * @param event group event
* @param event
*/ */
@Subscribe @Subscribe
public void onEvent(GroupEvent event) public void onEvent(GroupEvent event)
{ {
if (event.getEventType().isPost()) if (event.getEventType().isPost())
{ {
if (logger.isDebugEnabled()) Group group = event.getItem();
if (event instanceof GroupModificationEvent)
{ {
logger.debug("clear cache, because group {} has changed", Group beforeModification = ((GroupModificationEvent) event).getItemBeforeModification();
event.getItem().getId()); if (shouldCacheBeCleared(group, beforeModification))
{
logger.debug("clear cache, because group {} has changed", group.getId());
cache.clear();
}
else
{
logger.debug(
"cache of group {} is not invalidated, because non relevant fields have changed",
group.getId()
);
}
}
else
{
logger.debug("clear cache, because group {} has changed", group.getId());
cache.clear();
} }
cache.clear();
} }
} }
private boolean shouldCacheBeCleared(Group group, Group beforeModification)
{
return !group.getMembers().equals(beforeModification.getMembers());
}
/** /**
* Method description * Method description
* *
@@ -356,14 +383,14 @@ public class AuthorizationCollector
{ {
List<StoredAssignedPermission> globalPermissions = List<StoredAssignedPermission> globalPermissions =
securitySystem.getPermissions(new Predicate<AssignedPermission>() securitySystem.getPermissions(new Predicate<AssignedPermission>()
{
@Override
public boolean apply(AssignedPermission input)
{ {
return isUserPermitted(user, groups, input);
} @Override
}); public boolean apply(AssignedPermission input)
{
return isUserPermitted(user, groups, input);
}
});
for (StoredAssignedPermission gp : globalPermissions) for (StoredAssignedPermission gp : globalPermissions)
{ {
@@ -414,8 +441,8 @@ public class AuthorizationCollector
private void collectRepositoryPermissions(Builder<Permission> builder, private void collectRepositoryPermissions(Builder<Permission> builder,
Repository repository, User user, GroupNames groups) Repository repository, User user, GroupNames groups)
{ {
List<sonia.scm.repository.Permission> repositoryPermissions = List<sonia.scm.repository.Permission> repositoryPermissions
repository.getPermissions(); = repository.getPermissions();
if (Util.isNotEmpty(repositoryPermissions)) if (Util.isNotEmpty(repositoryPermissions))
{ {
@@ -426,7 +453,7 @@ public class AuthorizationCollector
{ {
hasPermission = true; hasPermission = true;
RepositoryPermission rp = new RepositoryPermission(repository, RepositoryPermission rp = new RepositoryPermission(repository,
permission.getType()); permission.getType());
if (logger.isTraceEnabled()) if (logger.isTraceEnabled())
{ {
@@ -589,7 +616,6 @@ public class AuthorizationCollector
private final String username; private final String username;
} }
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */ /** Field description */

View File

@@ -59,6 +59,7 @@ import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager; import sonia.scm.cache.CacheManager;
import sonia.scm.group.Group; import sonia.scm.group.Group;
import sonia.scm.group.GroupEvent; import sonia.scm.group.GroupEvent;
import sonia.scm.group.GroupModificationEvent;
import sonia.scm.group.GroupNames; import sonia.scm.group.GroupNames;
import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
@@ -163,6 +164,25 @@ public class AuthorizationCollectorTest {
verify(cache).clear(); verify(cache).clear();
} }
/**
* Tests {@link AuthorizationCollector#onEvent(sonia.scm.group.GroupEvent)} with modified groups.
*/
@Test
public void testOnGroupModificationEvent()
{
Group group = new Group("xml", "base");
Group modifiedGroup = new Group("xml", "base");
collector.onEvent(new GroupModificationEvent(modifiedGroup, group, HandlerEvent.BEFORE_MODIFY));
verify(cache, never()).clear();
collector.onEvent(new GroupModificationEvent(modifiedGroup, group, HandlerEvent.MODIFY));
verify(cache, never()).clear();
modifiedGroup.add("test");
collector.onEvent(new GroupModificationEvent(modifiedGroup, group, HandlerEvent.MODIFY));
verify(cache).clear();
}
/** /**
* Tests {@link AuthorizationCollector#onEvent(sonia.scm.repository.RepositoryEvent)}. * Tests {@link AuthorizationCollector#onEvent(sonia.scm.repository.RepositoryEvent)}.
*/ */