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.Set;
import sonia.scm.Filter;
import sonia.scm.group.Group;
import sonia.scm.group.GroupModificationEvent;
import sonia.scm.repository.RepositoryModificationEvent;
import sonia.scm.user.UserModificationEvent;
@@ -183,7 +185,8 @@ public class AuthorizationCollector
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);
cache.removeAll(new Filter<CacheKey>()
{
@@ -279,24 +282,48 @@ 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
* @param event group event
*/
@Subscribe
public void onEvent(GroupEvent event)
{
if (event.getEventType().isPost())
{
if (logger.isDebugEnabled())
Group group = event.getItem();
if (event instanceof GroupModificationEvent)
{
logger.debug("clear cache, because group {} has changed",
event.getItem().getId());
}
Group beforeModification = ((GroupModificationEvent) event).getItemBeforeModification();
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();
}
}
}
private boolean shouldCacheBeCleared(Group group, Group beforeModification)
{
return !group.getMembers().equals(beforeModification.getMembers());
}
/**
@@ -414,8 +441,8 @@ public class AuthorizationCollector
private void collectRepositoryPermissions(Builder<Permission> builder,
Repository repository, User user, GroupNames groups)
{
List<sonia.scm.repository.Permission> repositoryPermissions =
repository.getPermissions();
List<sonia.scm.repository.Permission> repositoryPermissions
= repository.getPermissions();
if (Util.isNotEmpty(repositoryPermissions))
{
@@ -589,7 +616,6 @@ public class AuthorizationCollector
private final String username;
}
//~--- fields ---------------------------------------------------------------
/** Field description */

View File

@@ -59,6 +59,7 @@ import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
import sonia.scm.group.Group;
import sonia.scm.group.GroupEvent;
import sonia.scm.group.GroupModificationEvent;
import sonia.scm.group.GroupNames;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
@@ -163,6 +164,25 @@ public class AuthorizationCollectorTest {
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)}.
*/