diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/pom.xml b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/pom.xml index ec828e0802..4e1b27ecbc 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/pom.xml +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/pom.xml @@ -42,7 +42,6 @@ org.apache.felix maven-bundle-plugin - 1.4.0 true @@ -58,8 +57,8 @@ javax.sql, javax.cache, javax.naming, - javax.xml.*, javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional, + javax.xml.*, org.w3c.dom, io.entgra.device.mgt.core.policy.mgt.common.*, org.wso2.carbon.user.core.*, @@ -69,7 +68,6 @@ io.entgra.device.mgt.core.device.mgt.core.*, io.entgra.device.mgt.core.device.mgt.common.*, org.wso2.carbon.ntask.*, - org.wso2.carbon.caching.* !io.entgra.device.mgt.core.policy.mgt.core.internal, @@ -246,6 +244,12 @@ io.entgra.device.mgt.core.server.bootup.heartbeat.beacon test + + + + com.google.guava + guava + diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheException.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheException.java new file mode 100644 index 0000000000..a0693ea3e2 --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheException.java @@ -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); + } +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheKey.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheKey.java new file mode 100644 index 0000000000..905023928f --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheKey.java @@ -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; + } +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheManager.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheManager.java new file mode 100644 index 0000000000..ced8861a40 --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/GuavaPolicyCacheManager.java @@ -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 getPolicies(List policyIds) throws PolicyManagementException; + + /* return all polices - ensures to return all the policies exists in the database */ + List getAllPolicies() throws PolicyManagementException; + + List 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 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 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; +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/impl/GuavaPolicyCacheManagerImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/impl/GuavaPolicyCacheManagerImpl.java new file mode 100644 index 0000000000..38ff2b6e8b --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/impl/GuavaPolicyCacheManagerImpl.java @@ -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 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 getPolicies(List policyIds) throws PolicyManagementException { + List resultPolicyList; + Map 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 getAllPolicies() throws PolicyManagementException { + PolicyManager policyManager = new PolicyManagerImpl(); + List tenantSpecificPolicyIds = policyManager.getAllPolicyIds(); + return getPolicies(tenantSpecificPolicyIds); + } + + @Override + public List getAllPolicies(String deviceType) throws PolicyManagementException { + List 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 policies) { + Map 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 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 generateCacheKeys(List policyIds) { + return policyIds.stream().map(GuavaPolicyCacheKey::new).collect(Collectors.toList()); + } +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheBuilder.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheBuilder.java new file mode 100644 index 0000000000..7af72aa1c3 --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheBuilder.java @@ -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 cacheLoader; + + private CacheBuilder cacheBuilder; + + public static final Policy NULL = new Policy(); + + public GuavaPolicyCacheBuilder withCacheLoader() { + cacheLoader = new CacheLoader() { + @Override + public Policy load(GuavaPolicyCacheKey key) throws Exception { + return singleLoad(key); + } + + @Override + public Map loadAll(Iterable 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 bulkLoad(Iterable keys) throws PolicyManagementException { + PolicyManager policyManager = new PolicyManagerImpl(); + + Map cacheMap = new HashMap<>(); + for(GuavaPolicyCacheKey key : keys) { + cacheMap.put(key, NULL); + } + + List 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 build() { + return cacheBuilder.build(cacheLoader); + } +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheConstants.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheConstants.java new file mode 100644 index 0000000000..ca4dba9912 --- /dev/null +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/cache/guava/utils/GuavaPolicyCacheConstants.java @@ -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; +} diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/FeatureDAO.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/FeatureDAO.java index 110631cc5e..cbd22cd05c 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/FeatureDAO.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/FeatureDAO.java @@ -123,4 +123,6 @@ public interface FeatureDAO { */ boolean deleteProfileFeatures(int featureId) throws FeatureManagerDAOException; + List getProfileFeatures(List profileIds) throws FeatureManagerDAOException; + } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/PolicyDAO.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/PolicyDAO.java index a755a5c6b3..b0c8efc354 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/PolicyDAO.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/PolicyDAO.java @@ -208,4 +208,6 @@ public interface PolicyDAO { * @throws PolicyManagerDAOException when there is an error while retrieving the policies from database */ List getAllPolicies(PolicyPaginationRequest request) throws PolicyManagerDAOException; + + List getAllPolicyIds() throws PolicyManagerDAOException; } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/ProfileDAO.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/ProfileDAO.java index e79c525401..4deb55821b 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/ProfileDAO.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/ProfileDAO.java @@ -86,4 +86,6 @@ public interface ProfileDAO { */ List getProfilesOfDeviceType(String deviceType) throws ProfileManagerDAOException; + List getProfiles(List profileIds) throws ProfileManagerDAOException; + } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/ProfileDAOImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/ProfileDAOImpl.java index 05bf17ed16..de8bbfab49 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/ProfileDAOImpl.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/ProfileDAOImpl.java @@ -34,6 +34,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class ProfileDAOImpl implements ProfileDAO { @@ -281,6 +282,39 @@ public class ProfileDAOImpl implements ProfileDAO { return profileList; } + @Override + public List getProfiles(List profileIds) throws ProfileManagerDAOException { + Connection connection; + PreparedStatement stmt = null; + ResultSet resultSet = null; + List profileList = new ArrayList<>(); + String profileIdsSQL = profileIds.stream().map(String::valueOf).collect(Collectors.joining(", ", "(", ")")); + try { + connection = this.getConnection(); + String query = "SELECT * FROM DM_PROFILE WHERE ID IN (?)"; + query = query.replace("(?)", profileIdsSQL); + stmt = connection.prepareStatement(query); + resultSet = stmt.executeQuery(); + + while(resultSet.next()) { + Profile profile = new Profile(); + profile.setProfileId(resultSet.getInt("ID")); + profile.setProfileName(resultSet.getString("PROFILE_NAME")); + profile.setTenantId(resultSet.getInt("TENANT_ID")); + profile.setDeviceType(resultSet.getString("DEVICE_TYPE")); + profile.setCreatedDate(resultSet.getTimestamp("CREATED_TIME")); + profile.setUpdatedDate(resultSet.getTimestamp("UPDATED_TIME")); + profileList.add(profile); + } + } catch (SQLException e) { + String msg = "Error occurred while reading the profile list "+profileIds.toString()+" from the database."; + log.error(msg, e); + throw new ProfileManagerDAOException(msg, e); + }finally { + PolicyManagementDAOUtil.cleanupResources(stmt, null); + } + return profileList; + } private Connection getConnection() throws ProfileManagerDAOException { return PolicyManagementDAOFactory.getConnection(); diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/feature/AbstractFeatureDAO.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/feature/AbstractFeatureDAO.java index 71b4a3a728..f5f39d5ec1 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/feature/AbstractFeatureDAO.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/feature/AbstractFeatureDAO.java @@ -39,6 +39,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * Abstract implementation of FeatureDAO which holds generic SQL queries. @@ -311,6 +312,71 @@ public abstract class AbstractFeatureDAO implements FeatureDAO { return featureList; } + @Override + public List getProfileFeatures(List profileIds) throws FeatureManagerDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + List featureList = new ArrayList(); + String profileIdsSQL = profileIds.stream().map(String::valueOf).collect(Collectors.joining(", ", "(", ")")); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + + try { + conn = this.getConnection(); + String query = "SELECT ID, PROFILE_ID, FEATURE_CODE, DEVICE_TYPE, CONTENT FROM DM_PROFILE_FEATURES " + + "WHERE TENANT_ID = ? AND PROFILE_ID IN (?)"; + query = query.replace("(?)", profileIdsSQL); + stmt = conn.prepareStatement(query); + stmt.setInt(1, tenantId); + resultSet = stmt.executeQuery(); + + while (resultSet.next()) { + + ProfileFeature profileFeature = new ProfileFeature(); + profileFeature.setFeatureCode(resultSet.getString("FEATURE_CODE")); + profileFeature.setDeviceType(resultSet.getString("DEVICE_TYPE")); + profileFeature.setId(resultSet.getInt("ID")); + profileFeature.setProfileId(resultSet.getInt("PROFILE_ID")); + + ByteArrayInputStream bais = null; + ObjectInputStream ois = null; + byte[] contentBytes; + try { + contentBytes = (byte[]) resultSet.getBytes("CONTENT"); + bais = new ByteArrayInputStream(contentBytes); + ois = new ObjectInputStream(bais); + profileFeature.setContent((Object) ois.readObject().toString()); + } finally { + if (bais != null) { + try { + bais.close(); + } catch (IOException e) { + log.warn("Error occurred while closing ByteArrayOutputStream", e); + } + } + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + log.warn("Error occurred while closing ObjectOutputStream", e); + } + } + } + + featureList.add(profileFeature); + } + } catch (SQLException e) { + throw new FeatureManagerDAOException("Unable to get the list of the features from database.", e); + } catch (IOException e) { + throw new FeatureManagerDAOException("Unable to read the byte stream for content", e); + } catch (ClassNotFoundException e) { + throw new FeatureManagerDAOException("Class not found while converting the object", e); + } finally { + PolicyManagementDAOUtil.cleanupResources(stmt, resultSet); + } + return featureList; + } + private Connection getConnection() throws FeatureManagerDAOException { return PolicyManagementDAOFactory.getConnection(); } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/policy/AbstractPolicyDAOImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/policy/AbstractPolicyDAOImpl.java index 85bd77d859..b681ce013a 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/policy/AbstractPolicyDAOImpl.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/dao/impl/policy/AbstractPolicyDAOImpl.java @@ -48,6 +48,7 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; /** * Abstract implementation of PolicyDAO which holds generic SQL queries. @@ -1824,6 +1825,58 @@ public abstract class AbstractPolicyDAOImpl implements PolicyDAO { } } + // return tenant specific policy Ids + @Override + public List getAllPolicyIds() throws PolicyManagerDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + + List policyIdsInDB = new ArrayList<>(); + try { + conn = this.getConnection(); + String query = "SELECT ID FROM DM_POLICY WHERE TENANT_ID = ?"; + stmt = conn.prepareStatement(query); + stmt.setInt(1, tenantId); + resultSet = stmt.executeQuery(); + while(resultSet.next()) { + policyIdsInDB.add(resultSet.getInt("ID")); + } + return policyIdsInDB; + } catch (SQLException e) { + String msg = "Error occurred while reading the policies from the database "; + log.error(msg, e); + throw new PolicyManagerDAOException(msg, e); + } finally { + PolicyManagementDAOUtil.cleanupResources(stmt, resultSet); + } + } + + public List getPolicies(List policyIds) throws PolicyManagerDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + String policyIdsSQL = policyIds.stream().map(String::valueOf).collect(Collectors.joining(", ", "(", ")")); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + + try { + conn = this.getConnection(); + String query = "SELECT * FROM DM_POLICY WHERE TENANT_ID = ? AND ID IN (?)"; + query = query.replace("(?)", policyIdsSQL); + stmt = conn.prepareStatement(query); + stmt.setInt(1, tenantId); + resultSet = stmt.executeQuery(); + + return this.extractPolicyListFromDbResult(resultSet, tenantId); + } catch (SQLException e) { + throw new PolicyManagerDAOException("Error occurred while reading the policy list "+policyIds.toString()+" from the database", e); + } finally { + PolicyManagementDAOUtil.cleanupResources(stmt, resultSet); + } + } + protected List extractPolicyListFromDbResult(ResultSet resultSet, int tenantId) throws SQLException { List policies = new ArrayList<>(); while (resultSet.next()) { diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/impl/PolicyAdministratorPointImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/impl/PolicyAdministratorPointImpl.java index 2521eab3a1..2f707305a9 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/impl/PolicyAdministratorPointImpl.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/impl/PolicyAdministratorPointImpl.java @@ -19,12 +19,11 @@ package io.entgra.device.mgt.core.policy.mgt.core.impl; import io.entgra.device.mgt.core.device.mgt.common.PolicyPaginationRequest; +import io.entgra.device.mgt.core.policy.mgt.core.cache.guava.impl.GuavaPolicyCacheManagerImpl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; -import io.entgra.device.mgt.core.device.mgt.common.DynamicTaskContext; -import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Policy; import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Profile; import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager; @@ -34,8 +33,6 @@ import org.wso2.carbon.ntask.core.TaskInfo; import org.wso2.carbon.ntask.core.TaskManager; import org.wso2.carbon.ntask.core.service.TaskService; import io.entgra.device.mgt.core.policy.mgt.common.*; -import io.entgra.device.mgt.core.policy.mgt.core.cache.PolicyCacheManager; -import io.entgra.device.mgt.core.policy.mgt.core.cache.impl.PolicyCacheManagerImpl; import io.entgra.device.mgt.core.policy.mgt.core.internal.PolicyManagementDataHolder; import io.entgra.device.mgt.core.policy.mgt.core.mgt.PolicyManager; import io.entgra.device.mgt.core.policy.mgt.core.mgt.ProfileManager; @@ -67,7 +64,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public Policy addPolicy(Policy policy) throws PolicyManagementException { Policy resultantPolicy = policyManager.addPolicy(policy); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().addPolicy(resultantPolicy); } return resultantPolicy; } @@ -76,7 +74,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public Policy updatePolicy(Policy policy) throws PolicyManagementException { Policy resultantPolicy = policyManager.updatePolicy(policy); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().updatePolicy(resultantPolicy); } return resultantPolicy; } @@ -85,7 +84,10 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public boolean updatePolicyPriorities(List policies) throws PolicyManagementException { boolean bool = policyManager.updatePolicyPriorities(policies); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + if(bool) { + GuavaPolicyCacheManagerImpl.getInstance().updatePolicies(policies); + } } return bool; } @@ -94,7 +96,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public void activatePolicy(int policyId) throws PolicyManagementException { policyManager.activatePolicy(policyId); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().refreshPolicy(policyId); } } @@ -102,7 +105,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public void inactivatePolicy(int policyId) throws PolicyManagementException { policyManager.inactivatePolicy(policyId); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().refreshPolicy(policyId); } } @@ -110,8 +114,11 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public boolean deletePolicy(Policy policy) throws PolicyManagementException { boolean bool = policyManager.deletePolicy(policy); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManager policyCacheManager = PolicyCacheManagerImpl.getInstance(); - policyCacheManager.rePopulateCache(); + //PolicyCacheManager policyCacheManager = PolicyCacheManagerImpl.getInstance(); + //policyCacheManager.rePopulateCache(); + if(bool) { + GuavaPolicyCacheManagerImpl.getInstance().invalidatePolicy(policy); + } } return bool; } @@ -120,8 +127,11 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public boolean deletePolicy(int policyId) throws PolicyManagementException { boolean bool = policyManager.deletePolicy(policyId); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManager policyCacheManager = PolicyCacheManagerImpl.getInstance(); - policyCacheManager.rePopulateCache(); + //PolicyCacheManager policyCacheManager = PolicyCacheManagerImpl.getInstance(); + //policyCacheManager.rePopulateCache(); + if(bool) { + GuavaPolicyCacheManagerImpl.getInstance().invalidatePolicy(policyId); + } } return bool; } @@ -190,7 +200,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { PolicyManagementException { policy = policyManager.addPolicyToDevice(deviceIdentifierList, policy); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().updatePolicy(policy); } return policy; } @@ -199,7 +210,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { public Policy addPolicyToRole(List roleNames, Policy policy) throws PolicyManagementException { policy = policyManager.addPolicyToRole(roleNames, policy); if (policyConfiguration.getCacheEnable()) { - PolicyCacheManagerImpl.getInstance().rePopulateCache(); + //PolicyCacheManagerImpl.getInstance().rePopulateCache(); + GuavaPolicyCacheManagerImpl.getInstance().updatePolicy(policy); } return policy; } @@ -207,7 +219,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { @Override public List getPolicies() throws PolicyManagementException { if (policyConfiguration.getCacheEnable()) { - return PolicyCacheManagerImpl.getInstance().getAllPolicies(); + //return PolicyCacheManagerImpl.getInstance().getAllPolicies(); + return GuavaPolicyCacheManagerImpl.getInstance().getAllPolicies(); } else { return policyManager.getPolicies(); } @@ -216,7 +229,8 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { @Override public Policy getPolicy(int policyId) throws PolicyManagementException { if (policyConfiguration.getCacheEnable()) { - return PolicyCacheManagerImpl.getInstance().getPolicy(policyId); + //return PolicyCacheManagerImpl.getInstance().getPolicy(policyId); + return GuavaPolicyCacheManagerImpl.getInstance().getPolicy(policyId); } else { return policyManager.getPolicy(policyId); } @@ -319,17 +333,19 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { @Override public int getPolicyCount() throws PolicyManagementException { - if (policyConfiguration.getCacheEnable()) { - return PolicyCacheManagerImpl.getInstance().getAllPolicies().size(); - } else { - return policyManager.getPolicyCount(); - } + //if (policyConfiguration.getCacheEnable()) { + //return PolicyCacheManagerImpl.getInstance().getAllPolicies().size(); + //return GuavaPolicyCacheManagerImpl.getInstance().getAllPoliciesCount(); + //} else { + return policyManager.getAllPolicyIds().size(); + //} } @Override public List getPolicies(String policyType) throws PolicyManagementException { if (policyConfiguration.getCacheEnable()) { - return PolicyCacheManagerImpl.getInstance().getAllPolicies(policyType); + //return PolicyCacheManagerImpl.getInstance().getAllPolicies(policyType); + return GuavaPolicyCacheManagerImpl.getInstance().getAllPolicies(policyType); } else { return policyManager.getPolicies(policyType); } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/PolicyManager.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/PolicyManager.java index abecb53712..2102ffe5db 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/PolicyManager.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/PolicyManager.java @@ -100,4 +100,8 @@ public interface PolicyManager { * while retrieving device groups */ List getPolicyList(PolicyPaginationRequest request) throws PolicyManagementException; + + List getAllPolicyIds() throws PolicyManagementException; + + List getPolicies(List policyIds) throws PolicyManagementException; } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/ProfileManager.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/ProfileManager.java index ccaf4005b5..5fb47142bc 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/ProfileManager.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/ProfileManager.java @@ -37,4 +37,6 @@ public interface ProfileManager { List getAllProfiles() throws ProfileManagementException; List getProfilesOfDeviceType(String deviceType) throws ProfileManagementException; + + List getProfiles(List profileIds) throws ProfileManagementException; } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/PolicyManagerImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/PolicyManagerImpl.java index fd5b3b5fdb..6bec219069 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/PolicyManagerImpl.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/PolicyManagerImpl.java @@ -70,6 +70,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class PolicyManagerImpl implements PolicyManager { @@ -1521,4 +1522,46 @@ public class PolicyManagerImpl implements PolicyManager { } return policyList; } + + @Override + public List getAllPolicyIds() throws PolicyManagementException { + try { + PolicyManagementDAOFactory.openConnection(); + return policyDAO.getAllPolicyIds(); + } catch (PolicyManagerDAOException ex) { + throw new PolicyManagementException("Error occurred while getting all the policy ids.", ex); + } catch (SQLException ex) { + throw new PolicyManagementException("Error occurred while opening a connection to the data source", ex); + } finally { + PolicyManagementDAOFactory.closeConnection(); + } + } + + public List getPolicies(List policyIds) throws PolicyManagementException { + + List policyList; + List profileList; + try { + PolicyManagementDAOFactory.openConnection(); + policyList = policyDAO.getAllPolicies(); + List profileIds = policyList.stream().map(Policy::getProfileId).collect(Collectors.toList()); + profileList = profileManager.getProfiles(profileIds); + this.buildPolicyList(policyList, profileList); + } catch (PolicyManagerDAOException e) { + throw new PolicyManagementException("Error occurred while getting all the policies.", e); + } catch (SQLException e) { + throw new PolicyManagementException("Error occurred while opening a connection to the data source", e); + } catch (GroupManagementException e) { + throw new PolicyManagementException("Error occurred while getting device groups.", e); + } catch (ProfileManagementException e) { + throw new PolicyManagementException("Error occurred while getting all the profiles.", e); + } finally { + PolicyManagementDAOFactory.closeConnection(); + } + // connection is already closed + for (Policy policy : policyList) { + policy.setDevices(this.getPolicyAppliedDevicesIds(policy.getId())); + } + return policyList; + } } diff --git a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/ProfileManagerImpl.java b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/ProfileManagerImpl.java index 96979f7aca..222fd964c1 100644 --- a/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/ProfileManagerImpl.java +++ b/components/policy-mgt/io.entgra.device.mgt.core.policy.mgt.core/src/main/java/io/entgra/device/mgt/core/policy/mgt/core/mgt/impl/ProfileManagerImpl.java @@ -221,4 +221,34 @@ public class ProfileManagerImpl implements ProfileManager { } return profileList; } + + @Override + public List getProfiles(List profileIds) throws ProfileManagementException { + List profileList; + try { + PolicyManagementDAOFactory.openConnection(); + profileList = profileDAO.getProfiles(profileIds); + List featureList = featureDAO.getProfileFeatures(profileIds); + + for (Profile profile : profileList) { + + List list = new ArrayList<>(); + for (ProfileFeature profileFeature : featureList) { + if (profile.getProfileId() == profileFeature.getProfileId()) { + list.add(profileFeature); + } + } + profile.setProfileFeaturesList(list); + } + } catch (ProfileManagerDAOException e) { + throw new ProfileManagementException("Error occurred while getting profiles", e); + } catch (FeatureManagerDAOException e) { + throw new ProfileManagementException("Error occurred while getting features related to profiles", e); + } catch (SQLException e) { + throw new ProfileManagementException("Error occurred while opening a connection to the data source", e); + } finally { + PolicyManagementDAOFactory.closeConnection(); + } + return profileList; + } }