This is an automated email from the ASF dual-hosted git repository. nic pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kylin.git
commit 84064d32a64c9f942e6c4cc0e1fac243a5ee2b89 Author: Zhong, Yanghong <nju_y...@apache.org> AuthorDate: Wed May 20 16:41:45 2020 +0800 KYLIN-4505 Change guava cache to spring cache for user authentication --- .../kylin/cache/cachemanager/CacheConstants.java | 1 + .../cache/cachemanager/MemcachedCacheManager.java | 3 ++ .../rest/security/KylinAuthenticationProvider.java | 44 +++++++++++----------- .../kylin/rest/service/KylinUserService.java | 14 ------- .../org/apache/kylin/rest/service/UserService.java | 10 ++--- server/src/main/resources/ehcache-test.xml | 7 ++++ server/src/main/resources/ehcache.xml | 7 ++++ 7 files changed, 42 insertions(+), 44 deletions(-) diff --git a/cache/src/main/java/org/apache/kylin/cache/cachemanager/CacheConstants.java b/cache/src/main/java/org/apache/kylin/cache/cachemanager/CacheConstants.java index 07b15a5..12d0c7a 100644 --- a/cache/src/main/java/org/apache/kylin/cache/cachemanager/CacheConstants.java +++ b/cache/src/main/java/org/apache/kylin/cache/cachemanager/CacheConstants.java @@ -20,4 +20,5 @@ package org.apache.kylin.cache.cachemanager; public class CacheConstants { public static final String QUERY_CACHE = "StorageCache"; + public static final String USER_CACHE = "UserCache"; } \ No newline at end of file diff --git a/cache/src/main/java/org/apache/kylin/cache/cachemanager/MemcachedCacheManager.java b/cache/src/main/java/org/apache/kylin/cache/cachemanager/MemcachedCacheManager.java index f5acc6f..2ae49c8 100644 --- a/cache/src/main/java/org/apache/kylin/cache/cachemanager/MemcachedCacheManager.java +++ b/cache/src/main/java/org/apache/kylin/cache/cachemanager/MemcachedCacheManager.java @@ -59,8 +59,11 @@ public class MemcachedCacheManager extends AbstractCacheManager { protected Collection<? extends Cache> loadCaches() { Cache successCache = new MemCachedCacheAdaptor( new MemcachedChunkingCache(MemcachedCache.create(memcachedCacheConfig, CacheConstants.QUERY_CACHE))); + Cache userCache = new MemCachedCacheAdaptor( + new MemcachedCache(MemcachedCache.create(memcachedCacheConfig, CacheConstants.USER_CACHE, 86400))); addCache(successCache); + addCache(userCache); Collection<String> names = getCacheNames(); Collection<Cache> caches = Lists.newArrayList(); diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java index 7ea3957..590c15a 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java +++ b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java @@ -18,16 +18,22 @@ package org.apache.kylin.rest.security; +import static org.apache.kylin.cache.cachemanager.CacheConstants.USER_CACHE; + import java.nio.charset.Charset; import java.util.Arrays; -import java.util.concurrent.TimeUnit; + +import javax.annotation.PostConstruct; import org.apache.kylin.common.KylinConfig; import org.apache.kylin.rest.service.UserService; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -36,9 +42,7 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.util.Assert; -import org.apache.kylin.shaded.com.google.common.cache.CacheBuilder; -import org.apache.kylin.shaded.com.google.common.cache.RemovalListener; -import org.apache.kylin.shaded.com.google.common.cache.RemovalNotification; +import org.apache.kylin.shaded.com.google.common.base.Preconditions; import org.apache.kylin.shaded.com.google.common.hash.HashFunction; import org.apache.kylin.shaded.com.google.common.hash.Hashing; @@ -49,21 +53,13 @@ public class KylinAuthenticationProvider implements AuthenticationProvider { private static final Logger logger = LoggerFactory.getLogger(KylinAuthenticationProvider.class); - private final static org.apache.kylin.shaded.com.google.common.cache.Cache<String, Authentication> userCache = CacheBuilder.newBuilder() - .maximumSize(KylinConfig.getInstanceFromEnv().getServerUserCacheMaxEntries()) - .expireAfterWrite(KylinConfig.getInstanceFromEnv().getServerUserCacheExpireSeconds(), TimeUnit.SECONDS) - .removalListener(new RemovalListener<String, Authentication>() { - @Override - public void onRemoval(RemovalNotification<String, Authentication> notification) { - KylinAuthenticationProvider.logger.debug("User cache {} is removed due to {}", - notification.getKey(), notification.getCause()); - } - }).build(); - @Autowired @Qualifier("userService") UserService userService; + @Autowired + private CacheManager cacheManager; + //Embedded authentication provider private AuthenticationProvider authenticationProvider; @@ -76,19 +72,21 @@ public class KylinAuthenticationProvider implements AuthenticationProvider { hf = Hashing.murmur3_128(); } + @PostConstruct + public void init() { + Preconditions.checkNotNull(cacheManager, "cacheManager is not injected yet"); + } + @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { byte[] hashKey = hf.hashString(authentication.getName() + authentication.getCredentials(), Charset.defaultCharset()).asBytes(); String userKey = Arrays.toString(hashKey); - if (userService.isEvictCacheFlag()) { - userCache.invalidateAll(); - userService.setEvictCacheFlag(false); - } - Authentication authed = userCache.getIfPresent(userKey); - - if (null != authed) { + Authentication authed; + Cache.ValueWrapper authedUser = cacheManager.getCache(USER_CACHE).get(userKey); + if (authedUser != null) { + authed = (Authentication) authedUser.get(); SecurityContextHolder.getContext().setAuthentication(authed); } else { try { @@ -119,7 +117,7 @@ public class KylinAuthenticationProvider implements AuthenticationProvider { userService.updateUser(user); } - userCache.put(userKey, authed); + cacheManager.getCache(USER_CACHE).put(userKey, authed); } catch (AuthenticationException e) { logger.error("Failed to auth user: " + authentication.getName(), e); throw e; diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/KylinUserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/KylinUserService.java index 2e43ce4..1f93fc2 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/service/KylinUserService.java +++ b/server-base/src/main/java/org/apache/kylin/rest/service/KylinUserService.java @@ -111,18 +111,6 @@ public class KylinUserService implements UserService { protected ResourceStore aclStore; - private boolean evictCacheFlag = false; - - @Override - public boolean isEvictCacheFlag() { - return evictCacheFlag; - } - - @Override - public void setEvictCacheFlag(boolean evictCacheFlag) { - this.evictCacheFlag = evictCacheFlag; - } - @PostConstruct public void init() throws IOException { aclStore = ResourceStore.getStore(KylinConfig.getInstanceFromEnv()); @@ -156,7 +144,6 @@ public class KylinUserService implements UserService { } getKylinUserManager().update(managedUser); logger.trace("update user : {}", user.getUsername()); - setEvictCacheFlag(true); } @Override @@ -166,7 +153,6 @@ public class KylinUserService implements UserService { } getKylinUserManager().delete(userName); logger.trace("delete user : {}", userName); - setEvictCacheFlag(true); } @Override diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java index 90107a1..1734be2 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java +++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java @@ -18,17 +18,13 @@ package org.apache.kylin.rest.service; -import org.apache.kylin.rest.security.ManagedUser; -import org.springframework.security.provisioning.UserDetailsManager; - import java.io.IOException; import java.util.List; -public interface UserService extends UserDetailsManager { - - boolean isEvictCacheFlag(); +import org.apache.kylin.rest.security.ManagedUser; +import org.springframework.security.provisioning.UserDetailsManager; - void setEvictCacheFlag(boolean evictCacheFlag); +public interface UserService extends UserDetailsManager { List<ManagedUser> listUsers() throws IOException; diff --git a/server/src/main/resources/ehcache-test.xml b/server/src/main/resources/ehcache-test.xml index 5bd4d13..47942de 100644 --- a/server/src/main/resources/ehcache-test.xml +++ b/server/src/main/resources/ehcache-test.xml @@ -20,6 +20,13 @@ > <persistence strategy="none"/> </cache> + <cache name="UserCache" + eternal="false" + timeToLiveSeconds="10800" + memoryStoreEvictionPolicy="LRU" + > + <persistence strategy="none"/> + </cache> <cache name="ExceptionQueryCache" eternal="false" timeToIdleSeconds="86400" diff --git a/server/src/main/resources/ehcache.xml b/server/src/main/resources/ehcache.xml index c9efc13..ee10751 100644 --- a/server/src/main/resources/ehcache.xml +++ b/server/src/main/resources/ehcache.xml @@ -20,6 +20,13 @@ > <persistence strategy="none"/> </cache> + <cache name="UserCache" + eternal="false" + timeToIdleSeconds="86400" + memoryStoreEvictionPolicy="LRU" + > + <persistence strategy="none"/> + </cache> <cache name="ExceptionQueryCache" eternal="false" timeToIdleSeconds="86400"