forked from community/device-mgt-core
parent
2cf7cf8705
commit
ef1b3d28ea
@ -0,0 +1,30 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava;
|
||||
|
||||
import io.entgra.device.mgt.core.policy.mgt.common.PolicyManagementException;
|
||||
|
||||
public class GuavaPolicyCacheException extends PolicyManagementException {
|
||||
private static final long serialVersionUID = 458698541247633587L;
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public GuavaPolicyCacheException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GuavaPolicyCacheException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public GuavaPolicyCacheException(String errorMessage, Throwable cause) {
|
||||
super(cause);
|
||||
setErrorMessage(errorMessage);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava;
|
||||
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class GuavaPolicyCacheKey {
|
||||
private final int tenantId;
|
||||
private final int policyId;
|
||||
private volatile int hashCode;
|
||||
|
||||
public GuavaPolicyCacheKey(int policyId) {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
this.tenantId = tenantId;
|
||||
this.policyId = policyId;
|
||||
}
|
||||
|
||||
public int getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public int getPolicyId() {
|
||||
return policyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tenantId+"/"+policyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if(!(other instanceof GuavaPolicyCacheKey)) {
|
||||
return false;
|
||||
}
|
||||
GuavaPolicyCacheKey otherPolicyCacheKey = (GuavaPolicyCacheKey) other;
|
||||
return (tenantId == otherPolicyCacheKey.tenantId
|
||||
&& policyId == otherPolicyCacheKey.policyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if(hashCode == 0) {
|
||||
hashCode = Objects.hash(tenantId, policyId);
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava;
|
||||
|
||||
|
||||
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Policy;
|
||||
import io.entgra.device.mgt.core.policy.mgt.common.PolicyManagementException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface GuavaPolicyCacheManager {
|
||||
/*
|
||||
* return list of policies requested by policy ids,
|
||||
* if the requested ids contains invalid policy ids this will only return policies for valid ids
|
||||
* */
|
||||
List<Policy> getPolicies(List<Integer> policyIds) throws PolicyManagementException;
|
||||
|
||||
/* return all polices - ensures to return all the policies exists in the database */
|
||||
List<Policy> getAllPolicies() throws PolicyManagementException;
|
||||
|
||||
List<Policy> getAllPolicies(String deviceType) throws PolicyManagementException;
|
||||
|
||||
/*
|
||||
* return the policy requested by policy id,
|
||||
* if the requested id invalid this will return null
|
||||
* */
|
||||
Policy getPolicy(Policy policy) throws PolicyManagementException;
|
||||
|
||||
/*
|
||||
* return the policy requested by policy id,
|
||||
* if the requested id invalid this will return null
|
||||
* */
|
||||
Policy getPolicy(int policyId) throws PolicyManagementException;
|
||||
|
||||
/* add policy to the cache - make sure to execute when creating policies */
|
||||
void addPolicies(List<Policy> policies);
|
||||
|
||||
/* add policy to the cache - make sure to run when creating a policy */
|
||||
void addPolicy(Policy policy);
|
||||
|
||||
/* update the policies using provided policies */
|
||||
void updatePolicies(List<Policy> policies);
|
||||
|
||||
/* update the policies using provided policy */
|
||||
void updatePolicy(Policy policy);
|
||||
|
||||
void refreshPolicy(Policy policy);
|
||||
|
||||
void refreshPolicy(int policyId);
|
||||
|
||||
void invalidatePolicy(Policy policy);
|
||||
|
||||
void invalidatePolicy(int policyId);
|
||||
|
||||
void invalidateAll();
|
||||
|
||||
/* refresh the cache with newly loaded values from the database */
|
||||
void rePopulateCache() throws PolicyManagementException;
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava.impl;
|
||||
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Policy;
|
||||
import io.entgra.device.mgt.core.policy.mgt.common.PolicyManagementException;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.cache.guava.GuavaPolicyCacheKey;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.cache.guava.GuavaPolicyCacheManager;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.cache.guava.utils.GuavaPolicyCacheBuilder;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.mgt.PolicyManager;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.mgt.impl.PolicyManagerImpl;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GuavaPolicyCacheManagerImpl implements GuavaPolicyCacheManager {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GuavaPolicyCacheManagerImpl.class);
|
||||
|
||||
private static LoadingCache<GuavaPolicyCacheKey, Policy> policyCache;
|
||||
|
||||
private static volatile GuavaPolicyCacheManagerImpl policyCacheManager;
|
||||
|
||||
private GuavaPolicyCacheManagerImpl() {
|
||||
|
||||
}
|
||||
|
||||
public static GuavaPolicyCacheManagerImpl getInstance() {
|
||||
if(policyCacheManager == null) {
|
||||
synchronized (GuavaPolicyCacheManagerImpl.class) {
|
||||
if(policyCacheManager == null) {
|
||||
policyCacheManager = new GuavaPolicyCacheManagerImpl();
|
||||
setPolicyCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
return policyCacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Policy> getPolicies(List<Integer> policyIds) throws PolicyManagementException {
|
||||
List<Policy> resultPolicyList;
|
||||
Map<GuavaPolicyCacheKey, Policy> cacheMap;
|
||||
try {
|
||||
cacheMap = policyCache.getAll(generateCacheKeys(policyIds));
|
||||
resultPolicyList = cacheMap.values().stream().
|
||||
filter(policy -> policy != GuavaPolicyCacheBuilder.NULL).
|
||||
collect(Collectors.toList());
|
||||
} catch (ExecutionException ex) {
|
||||
log.error("Error occurred when retrieving policies from cache");
|
||||
throw new PolicyManagementException("Error occurred (fails to return policies for policy ids "+policyIds.toString()+")", ex);
|
||||
}
|
||||
return resultPolicyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Policy> getAllPolicies() throws PolicyManagementException {
|
||||
PolicyManager policyManager = new PolicyManagerImpl();
|
||||
List<Integer> tenantSpecificPolicyIds = policyManager.getAllPolicyIds();
|
||||
return getPolicies(tenantSpecificPolicyIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Policy> getAllPolicies(String deviceType) throws PolicyManagementException {
|
||||
List<Policy> allPolicies = getAllPolicies();
|
||||
return allPolicies.stream().
|
||||
filter(policy -> deviceType.equals(policy.getOwnershipType())).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy getPolicy(Policy policy) throws PolicyManagementException {
|
||||
return getPolicy(policy.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy getPolicy(int policyId) throws PolicyManagementException {
|
||||
Policy resultPolicy;
|
||||
try {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policyId);
|
||||
resultPolicy = policyCache.get(key);
|
||||
if(resultPolicy == GuavaPolicyCacheBuilder.NULL) {
|
||||
resultPolicy = null;
|
||||
}
|
||||
}catch (ExecutionException ex) {
|
||||
log.error("Error occurred when retrieving policy from cache");
|
||||
throw new PolicyManagementException("Error occurred (fails to fetch requested policy for policy id "+policyId+")", ex);
|
||||
}
|
||||
return resultPolicy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPolicies(List<Policy> policies) {
|
||||
Map<GuavaPolicyCacheKey, Policy> policyMap = new HashMap<>();
|
||||
for(Policy policy : policies) {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policy.getId());
|
||||
policyMap.put(key, policy);
|
||||
}
|
||||
policyCache.putAll(policyMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPolicy(Policy policy) {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policy.getId());
|
||||
policyCache.put(key, policy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePolicies(List<Policy> policies) {
|
||||
addPolicies(policies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePolicy(Policy policy) {
|
||||
addPolicy(policy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPolicy(Policy policy) {
|
||||
refreshPolicy(policy.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPolicy(int policyId) {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policyId);
|
||||
policyCache.refresh(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePolicy(Policy policy) {
|
||||
invalidatePolicy(policy.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePolicy(int policyId) {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policyId);
|
||||
policyCache.invalidate(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAll() {
|
||||
policyCache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rePopulateCache() throws PolicyManagementException {
|
||||
invalidateAll();
|
||||
getAllPolicies();
|
||||
}
|
||||
|
||||
private static void setPolicyCache() {
|
||||
GuavaPolicyCacheBuilder cacheBuilder = new GuavaPolicyCacheBuilder();
|
||||
policyCache = cacheBuilder.withCacheBuilder().withCacheLoader().build();
|
||||
}
|
||||
|
||||
private List<GuavaPolicyCacheKey> generateCacheKeys(List<Integer> policyIds) {
|
||||
return policyIds.stream().map(GuavaPolicyCacheKey::new).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava.utils;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Policy;
|
||||
import io.entgra.device.mgt.core.policy.mgt.common.PolicyManagementException;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.cache.guava.GuavaPolicyCacheKey;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.mgt.PolicyManager;
|
||||
import io.entgra.device.mgt.core.policy.mgt.core.mgt.impl.PolicyManagerImpl;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class GuavaPolicyCacheBuilder {
|
||||
private static final Log log = LogFactory.getLog(GuavaPolicyCacheBuilder.class);
|
||||
|
||||
private CacheLoader<GuavaPolicyCacheKey, Policy> cacheLoader;
|
||||
|
||||
private CacheBuilder<Object, Object> cacheBuilder;
|
||||
|
||||
public static final Policy NULL = new Policy();
|
||||
|
||||
public GuavaPolicyCacheBuilder withCacheLoader() {
|
||||
cacheLoader = new CacheLoader<GuavaPolicyCacheKey, Policy>() {
|
||||
@Override
|
||||
public Policy load(GuavaPolicyCacheKey key) throws Exception {
|
||||
return singleLoad(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<GuavaPolicyCacheKey, Policy> loadAll(Iterable<? extends GuavaPolicyCacheKey> keys) throws Exception {
|
||||
return bulkLoad(keys);
|
||||
}
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
private Policy singleLoad(GuavaPolicyCacheKey key) throws PolicyManagementException {
|
||||
PolicyManager policyManager = new PolicyManagerImpl();
|
||||
Policy policy = policyManager.getPolicy(key.getPolicyId());
|
||||
if(policy == null) {
|
||||
return NULL;
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
private Map<GuavaPolicyCacheKey, Policy> bulkLoad(Iterable<? extends GuavaPolicyCacheKey> keys) throws PolicyManagementException {
|
||||
PolicyManager policyManager = new PolicyManagerImpl();
|
||||
|
||||
Map<GuavaPolicyCacheKey, Policy> cacheMap = new HashMap<>();
|
||||
for(GuavaPolicyCacheKey key : keys) {
|
||||
cacheMap.put(key, NULL);
|
||||
}
|
||||
|
||||
List<Policy> policies = policyManager.getPolicies();
|
||||
for(Policy policy : policies) {
|
||||
GuavaPolicyCacheKey key = new GuavaPolicyCacheKey(policy.getId());
|
||||
cacheMap.put(key, policy);
|
||||
}
|
||||
return cacheMap;
|
||||
}
|
||||
|
||||
public GuavaPolicyCacheBuilder withCacheBuilder() {
|
||||
// TODO : refactor to use configuration file
|
||||
cacheBuilder = CacheBuilder.newBuilder().
|
||||
maximumSize(GuavaPolicyCacheConstants.MAX_ENTRIES).
|
||||
expireAfterWrite(GuavaPolicyCacheConstants.EXPIRE_AFTER_WRITE_IN_MIN, TimeUnit.MINUTES);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoadingCache<GuavaPolicyCacheKey, Policy> build() {
|
||||
return cacheBuilder.build(cacheLoader);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package io.entgra.device.mgt.core.policy.mgt.core.cache.guava.utils;
|
||||
|
||||
public final class GuavaPolicyCacheConstants {
|
||||
public static final long MAX_ENTRIES = 1000;
|
||||
|
||||
public static final long EXPIRE_AFTER_WRITE_IN_MIN = 30;
|
||||
}
|
Loading…
Reference in new issue