improve cache invalidation on user events

This commit is contained in:
Sebastian Sdorra
2016-06-26 12:20:32 +02:00
parent 8e3c3e4b63
commit 6428245506
2 changed files with 64 additions and 11 deletions

View File

@@ -71,6 +71,8 @@ import sonia.scm.util.Util;
import java.util.List;
import java.util.Set;
import sonia.scm.Filter;
import sonia.scm.user.UserModificationEvent;
/**
*
@@ -139,8 +141,13 @@ public class AuthorizationCollector
}
/**
* Method description
*
* Invalidates the cache of a user which was modified. The cache entries for the user will be invalidated for the
* following reasons:
* <ul>
* <li>Admin or Active flag was modified.</li>
* <li>New user created, for the case of old cache values</li>
* <li>User deleted</li>
* </ul>
*
* @param event
*/
@@ -150,18 +157,37 @@ public class AuthorizationCollector
if (event.getEventType().isPost())
{
User user = event.getItem();
if (logger.isDebugEnabled())
String username = user.getId();
if (event instanceof UserModificationEvent)
{
logger.debug(
"clear cache of user {}, because user properties have changed",
user.getName());
User beforeModification = ((UserModificationEvent) event).getItemBeforeModification();
if ( user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive() )
{
invalidateUserCache(username);
}
else
{
logger.debug("cache of user {} is not invalidated, because admin and active flag has not changed", username);
}
}
else
{
invalidateUserCache(username);
}
// check if this is neccessary
cache.clear();
}
}
private void invalidateUserCache(final String username){
logger.debug("invalidate cache of user {}, because user properties have changed", username);
cache.removeAll(new Filter<CacheKey>()
{
@Override
public boolean accept(CacheKey item)
{
return username.equalsIgnoreCase(item.username);
}
});
}
/**
* Method description

View File

@@ -53,6 +53,7 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.mockito.runners.MockitoJUnitRunner;
import sonia.scm.Filter;
import sonia.scm.HandlerEvent;
import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
@@ -66,6 +67,7 @@ import sonia.scm.repository.RepositoryEvent;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.User;
import sonia.scm.user.UserEvent;
import sonia.scm.user.UserModificationEvent;
import sonia.scm.user.UserTestData;
/**
@@ -118,7 +120,32 @@ public class AuthorizationCollectorTest {
verify(cache, never()).clear();
collector.onEvent(new UserEvent(user, HandlerEvent.CREATE));
verify(cache).clear();
verify(cache).removeAll(Mockito.any(Filter.class));
}
/**
* Tests {@link AuthorizationCollector#onEvent(sonia.scm.user.UserEvent)} with modified user.
*/
@Test
public void testOnUserModificationEvent()
{
User user = UserTestData.createDent();
User userModified = UserTestData.createDent();
userModified.setDisplayName("Super Dent");
collector.onEvent(new UserModificationEvent(userModified, user, HandlerEvent.BEFORE_CREATE));
verify(cache, never()).removeAll(Mockito.any(Filter.class));
collector.onEvent(new UserModificationEvent(userModified, user, HandlerEvent.CREATE));
verify(cache, never()).removeAll(Mockito.any(Filter.class));
userModified.setAdmin(true);
collector.onEvent(new UserModificationEvent(userModified, user, HandlerEvent.BEFORE_CREATE));
verify(cache, never()).removeAll(Mockito.any(Filter.class));
collector.onEvent(new UserModificationEvent(userModified, user, HandlerEvent.CREATE));
verify(cache).removeAll(Mockito.any(Filter.class));
}
/**