improve cache invalidation on repository events

This commit is contained in:
Sebastian Sdorra
2016-06-26 12:41:00 +02:00
parent 6428245506
commit a592484f0f
2 changed files with 66 additions and 4 deletions

View File

@@ -72,6 +72,7 @@ import sonia.scm.util.Util;
import java.util.List;
import java.util.Set;
import sonia.scm.Filter;
import sonia.scm.repository.RepositoryModificationEvent;
import sonia.scm.user.UserModificationEvent;
/**
@@ -161,7 +162,7 @@ public class AuthorizationCollector
if (event instanceof UserModificationEvent)
{
User beforeModification = ((UserModificationEvent) event).getItemBeforeModification();
if ( user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive() )
if ( shouldCacheBeCleared(user, beforeModification) )
{
invalidateUserCache(username);
}
@@ -177,6 +178,11 @@ public class AuthorizationCollector
}
}
private boolean shouldCacheBeCleared(User user, User beforeModification)
{
return user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive();
}
private void invalidateUserCache(final String username){
logger.debug("invalidate cache of user {}, because user properties have changed", username);
cache.removeAll(new Filter<CacheKey>()
@@ -200,14 +206,41 @@ public class AuthorizationCollector
{
if (event.getEventType().isPost())
{
Repository repository = event.getItem();
if (logger.isDebugEnabled())
{
logger.debug("clear cache, because repository {} has changed",
event.getItem().getName());
logger.debug("clear cache, because repository {} has changed", repository.getName());
}
if (event instanceof RepositoryModificationEvent)
{
Repository beforeModification = ((RepositoryModificationEvent) event).getItemBeforeModification();
if (shouldCacheBeCleared(repository, beforeModification))
{
logger.debug("clear cache, because a relevant field of repository {} has changed", repository.getName());
cache.clear();
}
else
{
logger.debug(
"cache of repository {} is not invalidated, because non relevant fields have changed",
repository.getName()
);
}
}
else
{
logger.debug("clear cache, because repository {} has changed", repository.getName());
cache.clear();
}
}
}
private boolean shouldCacheBeCleared(Repository repository, Repository beforeModification)
{
return repository.isArchived() != beforeModification.isArchived()
|| repository.isPublicReadable() != beforeModification.isPublicReadable()
|| ! repository.getPermissions().equals(beforeModification.getPermissions());
}
/**

View File

@@ -64,6 +64,7 @@ import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryDAO;
import sonia.scm.repository.RepositoryEvent;
import sonia.scm.repository.RepositoryModificationEvent;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.User;
import sonia.scm.user.UserEvent;
@@ -176,6 +177,34 @@ public class AuthorizationCollectorTest {
verify(cache).clear();
}
/**
* Tests {@link AuthorizationCollector#onEvent(sonia.scm.repository.RepositoryEvent)} with modified repository.
*/
@Test
public void testOnRepositoryModificationEvent()
{
Repository repositoryModified = RepositoryTestData.createHeartOfGold();
repositoryModified.setName("test123");
repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test")));
Repository repository = RepositoryTestData.createHeartOfGold();
repository.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test")));
collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.BEFORE_CREATE));
verify(cache, never()).clear();
collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE));
verify(cache, never()).clear();
repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test")));
collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE));
verify(cache, never()).clear();
repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test123")));
collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE));
verify(cache).clear();
}
/**
* Tests {@link AuthorizationCollector#onEvent(sonia.scm.security.StoredAssignedPermissionEvent)}.
*/