Skip to content

Commit

Permalink
Introduce caching
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaminduR committed Nov 24, 2023
1 parent eae014f commit c3cc8f8
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
import org.wso2.carbon.identity.application.mgt.dao.AuthorizedAPIDAO;
import org.wso2.carbon.identity.application.mgt.dao.impl.AuthorizedAPIDAOImpl;
import org.wso2.carbon.identity.application.mgt.dao.impl.CacheBackedAuthorizedAPIDAOImpl;
import org.wso2.carbon.identity.application.mgt.internal.ApplicationManagementServiceComponentHolder;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;

Expand All @@ -44,7 +45,7 @@
*/
public class AuthorizedAPIManagementServiceImpl implements AuthorizedAPIManagementService {

private final AuthorizedAPIDAO authorizedAPIDAO = new AuthorizedAPIDAOImpl();
private final AuthorizedAPIDAO authorizedAPIDAO = new CacheBackedAuthorizedAPIDAOImpl(new AuthorizedAPIDAOImpl());

@Override
public void addAuthorizedAPI(String applicationId, AuthorizedAPI authorizedAPI, String tenantDomain)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.application.mgt.cache;

import org.wso2.carbon.identity.core.cache.BaseCache;

/**
* Cache for authorized API.
*/
public class AuthorizedAPICache extends BaseCache<AuthorizedAPICacheKey, AuthorizedAPICacheEntry> {

private static final String CACHE_NAME = "AuthorizedAPICache";
private static volatile AuthorizedAPICache instance;

public AuthorizedAPICache(String cacheName) {

super(cacheName);
}

/**
* Get instance of AuthorizedAPICache.
*
* @return Instance of AuthorizedAPICache.
*/
public static AuthorizedAPICache getInstance() {

if (instance == null) {
synchronized (AuthorizedAPICache.class) {
if (instance == null) {
instance = new AuthorizedAPICache(CACHE_NAME);
}
}
}
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.application.mgt.cache;

import org.wso2.carbon.identity.application.common.model.AuthorizedAPI;

import java.io.Serializable;

/**
* Cache entry for authorized API.
*/
public class AuthorizedAPICacheEntry implements Serializable {

private AuthorizedAPI authorizedAPI;

public AuthorizedAPICacheEntry(AuthorizedAPI authorizedAPI) {

this.authorizedAPI = authorizedAPI;
}

public AuthorizedAPI getAuthorizedAPI() {

return authorizedAPI;
}

public void setAuthorizedAPI(AuthorizedAPI authorizedAPI) {

this.authorizedAPI = authorizedAPI;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.application.mgt.cache;

import java.io.Serializable;

/**
* Cache key for authorized API.
*/
public class AuthorizedAPICacheKey implements Serializable {

private static final long serialVersionUID = 3112605038259278777L;

private String appId;
private String apiId;

public AuthorizedAPICacheKey(String appId, String apiId) {

this.appId = appId;
this.apiId = apiId;
}

public String getAppId() {

return appId;
}

public void setAppId(String appId) {

this.appId = appId;
}

public String getApiId() {

return apiId;
}

public void setApiId(String apiId) {

this.apiId = apiId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.application.mgt.dao.impl;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.AuthorizedAPI;
import org.wso2.carbon.identity.application.common.model.AuthorizedScopes;
import org.wso2.carbon.identity.application.common.model.Scope;
import org.wso2.carbon.identity.application.mgt.cache.AuthorizedAPICache;
import org.wso2.carbon.identity.application.mgt.cache.AuthorizedAPICacheEntry;
import org.wso2.carbon.identity.application.mgt.cache.AuthorizedAPICacheKey;
import org.wso2.carbon.identity.application.mgt.dao.AuthorizedAPIDAO;

import java.util.List;

/**
* Cache backed implementation of {@link AuthorizedAPIDAO}.
*/
public class CacheBackedAuthorizedAPIDAOImpl implements AuthorizedAPIDAO {

private final AuthorizedAPIDAO authorizedAPIDAO;

private static AuthorizedAPICache authorizedAPICache;

private static final Log LOG = LogFactory.getLog(CacheBackedAuthorizedAPIDAOImpl.class);

public CacheBackedAuthorizedAPIDAOImpl(AuthorizedAPIDAO authorizedAPIDAO) {

this.authorizedAPIDAO = authorizedAPIDAO;
authorizedAPICache = AuthorizedAPICache.getInstance();
}

@Override
public void addAuthorizedAPI(String applicationId, String apiId, String policyId, List<Scope> scopes, int tenantId)
throws IdentityApplicationManagementException {


authorizedAPIDAO.addAuthorizedAPI(applicationId, apiId, policyId, scopes, tenantId);
}

@Override
public List<AuthorizedAPI> getAuthorizedAPIs(String applicationId, int tenantId)
throws IdentityApplicationManagementException {

return authorizedAPIDAO.getAuthorizedAPIs(applicationId, tenantId);
}

@Override
public void patchAuthorizedAPI(String appId, String apiId, List<String> addedScopes, List<String> removedScopes,
int tenantId) throws IdentityApplicationManagementException {

clearAuthorizedAPIFromCache(appId, apiId, tenantId);
authorizedAPIDAO.patchAuthorizedAPI(appId, apiId, addedScopes, removedScopes, tenantId);
}

@Override
public void deleteAuthorizedAPI(String appId, String apiId, int tenantId)
throws IdentityApplicationManagementException {

clearAuthorizedAPIFromCache(appId, apiId, tenantId);
authorizedAPIDAO.deleteAuthorizedAPI(appId, apiId, tenantId);
}

@Override
public List<AuthorizedScopes> getAuthorizedScopes(String applicationId, int tenantId)
throws IdentityApplicationManagementException {

return authorizedAPIDAO.getAuthorizedScopes(applicationId, tenantId);
}

@Override
public AuthorizedAPI getAuthorizedAPI(String appId, String apiId, int tenantId)
throws IdentityApplicationManagementException {

AuthorizedAPI authorizedAPI = getAuthorizedAPIFromCache(appId, apiId, tenantId);
if (authorizedAPI == null) {
try {
authorizedAPI = authorizedAPIDAO.getAuthorizedAPI(appId, apiId, tenantId);
if (authorizedAPI != null) {
addToCache(appId, apiId, authorizedAPI, tenantId);
}
} catch (IdentityApplicationManagementException e) {
String error = "Error while retrieving authorized API for application id: " + appId + " and api id: "
+ apiId + " in tenant id: " + tenantId;
LOG.error(error, e);
throw new IdentityApplicationManagementException(error, e);
}
}
return authorizedAPI != null ? authorizedAPI : authorizedAPIDAO.getAuthorizedAPI(appId, apiId, tenantId);
}

private AuthorizedAPI getAuthorizedAPIFromCache(String appId, String apiId, int tenantId) {

AuthorizedAPI authorizedAPI = null;
if (StringUtils.isNotBlank(appId)) {
AuthorizedAPICacheKey cacheKey = new AuthorizedAPICacheKey(appId, apiId);
AuthorizedAPICacheEntry cacheEntry = authorizedAPICache.getValueFromCache(cacheKey, tenantId);
if (cacheEntry != null) {
authorizedAPI = cacheEntry.getAuthorizedAPI();
}
} else {
LOG.debug("Application id is empty. Cannot retrieve authorized APIs from cache.");
}

if (authorizedAPI == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Authorized APIs not found in cache for application id: " + appId + " in tenant id: "
+ tenantId);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Authorized APIs found in cache for application id: " + appId + " in tenant id: "
+ tenantId);
}
}
return authorizedAPI;
}

private void addToCache(String appId, String apiId, AuthorizedAPI authorizedAPI, int tenantId) {

if (StringUtils.isNotBlank(appId)) {
AuthorizedAPICacheKey cacheKey = new AuthorizedAPICacheKey(appId, apiId);
AuthorizedAPICacheEntry cacheEntry = new AuthorizedAPICacheEntry(authorizedAPI);
authorizedAPICache.addToCache(cacheKey, cacheEntry, tenantId);
} else {
LOG.debug("Application id is empty. Cannot add authorized APIs to cache.");
}
}

private void clearAuthorizedAPIFromCache(String appId, String apiId, int tenantId) {

if (StringUtils.isNotBlank(appId)) {
AuthorizedAPICacheKey cacheKey = new AuthorizedAPICacheKey(appId, apiId);
authorizedAPICache.clearCacheEntry(cacheKey, tenantId);
} else {
LOG.debug("Application id is empty. Cannot clear authorized APIs from cache.");
}
}
}

0 comments on commit c3cc8f8

Please sign in to comment.