Merge pull request #948 from geethkokila/master

Adding the certificate caching to improve performance
revert-70aa11f8
Harshan Liyanage 7 years ago committed by GitHub
commit 42836a0704

@ -94,6 +94,7 @@
io.swagger.annotations.*;resolution:=optional, io.swagger.annotations.*;resolution:=optional,
org.wso2.carbon.device.mgt.core.*, org.wso2.carbon.device.mgt.core.*,
org.wso2.carbon.registry.indexing.*, org.wso2.carbon.registry.indexing.*,
javax.cache.*
<!--org.bouncycastle.pkcs.jcajce--> <!--org.bouncycastle.pkcs.jcajce-->
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.certificate.mgt.core.cache;
import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse;
/**
* This interface for caching the certificates.
*/
public interface CertificateCacheManager {
void addCertificateBySerial(String serialNumber, CertificateResponse certificate) ;
void addCertificateByCN(String commonName, CertificateResponse certificate) ;
CertificateResponse getCertificateBySerial(String serialNumber) ;
CertificateResponse getCertificateByCN(String commonName) ;
}

@ -0,0 +1,132 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.certificate.mgt.core.cache.impl;
import org.wso2.carbon.certificate.mgt.core.cache.CertificateCacheManager;
import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import javax.cache.Cache;
import javax.cache.CacheConfiguration;
import javax.cache.CacheManager;
import javax.cache.Caching;
import java.util.concurrent.TimeUnit;
public class CertificateCacheManagerImpl implements CertificateCacheManager {
public static final String CERTIFICATE_CACHE_MANAGER = "CERTIFICATE_CACHE_MANAGER";
public static final String CERTIFICATE_CACHE = "CERTIFICATE_CACHE";
private static boolean isCertificateCacheInitialized = false;
private static String SERIAL_PRE = "S_";
private static String COMMON_NAME_PRE = "C_";
private static CertificateCacheManager certificateCacheManager;
private CertificateCacheManagerImpl() {
}
public static CertificateCacheManager getInstance() {
if (certificateCacheManager == null) {
synchronized (CertificateCacheManagerImpl.class) {
if (certificateCacheManager == null) {
certificateCacheManager = new CertificateCacheManagerImpl();
}
}
}
return certificateCacheManager;
}
@Override
public void addCertificateBySerial(String serialNumber, CertificateResponse certificate) {
CertificateCacheManagerImpl.getCertificateCache().put(SERIAL_PRE + serialNumber, certificate);
}
@Override
public void addCertificateByCN(String commonName, CertificateResponse certificate) {
CertificateCacheManagerImpl.getCertificateCache().put(COMMON_NAME_PRE + commonName, certificate);
}
@Override
public CertificateResponse getCertificateBySerial(String serialNumber) {
return CertificateCacheManagerImpl.getCertificateCache().get(SERIAL_PRE + serialNumber);
}
@Override
public CertificateResponse getCertificateByCN(String commonName) {
return CertificateCacheManagerImpl.getCertificateCache().get(COMMON_NAME_PRE + commonName);
}
private static CacheManager getCacheManager() {
return Caching.getCacheManagerFactory().getCacheManager(CertificateCacheManagerImpl.CERTIFICATE_CACHE_MANAGER);
}
public static Cache<String, CertificateResponse> getCertificateCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
CacheManager manager = getCacheManager();
Cache<String, CertificateResponse> certificateCache = null;
if (config.getDeviceCacheConfiguration().isEnabled()) {
if (!isCertificateCacheInitialized) {
initializeCertificateCache();
}
if (manager != null) {
certificateCache = manager.<String, CertificateResponse>getCache(CertificateCacheManagerImpl.CERTIFICATE_CACHE);
} else {
certificateCache = Caching.getCacheManager(CertificateCacheManagerImpl.CERTIFICATE_CACHE_MANAGER).
<String, CertificateResponse>getCache(CertificateCacheManagerImpl.CERTIFICATE_CACHE);
}
}
return certificateCache;
}
public static void initializeCertificateCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
int certificateCacheExpiry = config.getCertificateCacheConfiguration().getExpiryTime();
CacheManager manager = getCacheManager();
if (config.getCertificateCacheConfiguration().isEnabled()) {
if (!isCertificateCacheInitialized) {
isCertificateCacheInitialized = true;
if (manager != null) {
if (certificateCacheExpiry > 0) {
manager.<String, CertificateResponse>createCacheBuilder(CertificateCacheManagerImpl.CERTIFICATE_CACHE).
setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS,
certificateCacheExpiry)).setExpiry(CacheConfiguration.ExpiryType.ACCESSED, new CacheConfiguration.
Duration(TimeUnit.SECONDS, certificateCacheExpiry)).setStoreByValue(true).build();
} else {
manager.<String, CertificateResponse>getCache(CertificateCacheManagerImpl.CERTIFICATE_CACHE);
}
} else {
if (certificateCacheExpiry > 0) {
Caching.getCacheManager().
<String, CertificateResponse>createCacheBuilder(CertificateCacheManagerImpl.CERTIFICATE_CACHE).
setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS,
certificateCacheExpiry)).setExpiry(CacheConfiguration.ExpiryType.ACCESSED, new CacheConfiguration.
Duration(TimeUnit.SECONDS, certificateCacheExpiry)).setStoreByValue(true).build();
} else {
Caching.getCacheManager().<String, CertificateResponse>getCache(CertificateCacheManagerImpl.CERTIFICATE_CACHE);
}
}
}
}
}
}

@ -19,6 +19,8 @@ package org.wso2.carbon.certificate.mgt.core.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.cache.CertificateCacheManager;
import org.wso2.carbon.certificate.mgt.core.cache.impl.CertificateCacheManagerImpl;
import org.wso2.carbon.certificate.mgt.core.config.CertificateConfigurationManager; import org.wso2.carbon.certificate.mgt.core.config.CertificateConfigurationManager;
import org.wso2.carbon.certificate.mgt.core.config.CertificateKeystoreConfig; import org.wso2.carbon.certificate.mgt.core.config.CertificateKeystoreConfig;
import org.wso2.carbon.certificate.mgt.core.dao.CertificateDAO; import org.wso2.carbon.certificate.mgt.core.dao.CertificateDAO;
@ -126,8 +128,8 @@ public class KeyStoreReader {
CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance(). CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance().
getCertificateKeyStoreConfig(); getCertificateKeyStoreConfig();
keyStore = loadKeyStore(certificateKeystoreConfig.getCertificateKeystoreType(), keyStore = loadKeyStore(certificateKeystoreConfig.getCertificateKeystoreType(),
certificateKeystoreConfig.getCertificateKeystoreLocation(), certificateKeystoreConfig.getCertificateKeystoreLocation(),
certificateKeystoreConfig.getCertificateKeystorePassword()); certificateKeystoreConfig.getCertificateKeystorePassword());
} catch (CertificateManagementException e) { } catch (CertificateManagementException e) {
String errorMsg = "Unable to find KeyStore configuration in certificate-mgt.config file."; String errorMsg = "Unable to find KeyStore configuration in certificate-mgt.config file.";
throw new KeystoreException(errorMsg, e); throw new KeystoreException(errorMsg, e);
@ -140,7 +142,7 @@ public class KeyStoreReader {
CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance(). CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance().
getCertificateKeyStoreConfig(); getCertificateKeyStoreConfig();
saveKeyStore(keyStore, certificateKeystoreConfig.getCertificateKeystoreLocation(), saveKeyStore(keyStore, certificateKeystoreConfig.getCertificateKeystoreLocation(),
certificateKeystoreConfig.getCertificateKeystorePassword()); certificateKeystoreConfig.getCertificateKeystorePassword());
} catch (CertificateManagementException e) { } catch (CertificateManagementException e) {
String errorMsg = "Unable to find KeyStore configuration in certificate-mgt.config file."; String errorMsg = "Unable to find KeyStore configuration in certificate-mgt.config file.";
throw new KeystoreException(errorMsg, e); throw new KeystoreException(errorMsg, e);
@ -251,7 +253,7 @@ public class KeyStoreReader {
CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance(). CertificateKeystoreConfig certificateKeystoreConfig = CertificateConfigurationManager.getInstance().
getCertificateKeyStoreConfig(); getCertificateKeyStoreConfig();
raPrivateKey = (PrivateKey) keystore.getKey(certificateKeystoreConfig.getRACertAlias(), raPrivateKey = (PrivateKey) keystore.getKey(certificateKeystoreConfig.getRACertAlias(),
certificateKeystoreConfig.getRAPrivateKeyPassword().toCharArray()); certificateKeystoreConfig.getRAPrivateKeyPassword().toCharArray());
} catch (UnrecoverableKeyException e) { } catch (UnrecoverableKeyException e) {
String errorMsg = "Key is unrecoverable when retrieving RA private key"; String errorMsg = "Key is unrecoverable when retrieving RA private key";
throw new KeystoreException(errorMsg, e); throw new KeystoreException(errorMsg, e);
@ -276,28 +278,36 @@ public class KeyStoreReader {
public CertificateResponse getCertificateBySerial(String serialNumber) throws KeystoreException { public CertificateResponse getCertificateBySerial(String serialNumber) throws KeystoreException {
CertificateResponse certificateResponse = null; CertificateResponse certificateResponse = null;
try { try {
CertificateManagementDAOFactory.openConnection(); CertificateCacheManager cacheManager = CertificateCacheManagerImpl.getInstance();
certificateResponse = certDao.retrieveCertificate(serialNumber); certificateResponse = cacheManager.getCertificateBySerial(serialNumber);
if (certificateResponse != null && certificateResponse.getCertificate() != null) { if (certificateResponse == null) {
Certificate certificate = (Certificate) Serializer.deserialize(certificateResponse.getCertificate()); try {
if (certificate instanceof X509Certificate) { CertificateManagementDAOFactory.openConnection();
X509Certificate x509cert = (X509Certificate) certificate; certificateResponse = certDao.retrieveCertificate(serialNumber);
String commonName = CertificateGenerator.getCommonName(x509cert); } catch (SQLException e) {
certificateResponse.setCommonName(commonName); String errorMsg = "Error when making a connection to the database.";
throw new KeystoreException(errorMsg, e);
} finally {
CertificateManagementDAOFactory.closeConnection();
}
if (certificateResponse != null && certificateResponse.getCertificate() != null) {
Certificate certificate = (Certificate) Serializer.deserialize(certificateResponse.getCertificate());
if (certificate instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate) certificate;
String commonName = CertificateGenerator.getCommonName(x509cert);
certificateResponse.setCommonName(commonName);
cacheManager.addCertificateBySerial(serialNumber, certificateResponse);
}
} }
} }
} catch (CertificateManagementDAOException e) { } catch (CertificateManagementDAOException e) {
String errorMsg = "Error when retrieving certificate from the the database for the serial number: " + String errorMsg = "Error when retrieving certificate from the the database for the serial number: " +
serialNumber; serialNumber;
throw new KeystoreException(errorMsg, e); throw new KeystoreException(errorMsg, e);
} catch (SQLException e) {
String errorMsg = "Error when making a connection to the database.";
throw new KeystoreException(errorMsg, e);
} catch (ClassNotFoundException | IOException e) { } catch (ClassNotFoundException | IOException e) {
String errorMsg = "Error when de-serializing saved certificate."; String errorMsg = "Error when de-serializing saved certificate.";
throw new KeystoreException(errorMsg, e); throw new KeystoreException(errorMsg, e);
} finally {
CertificateManagementDAOFactory.closeConnection();
} }
return certificateResponse; return certificateResponse;
} }

@ -17,6 +17,7 @@
*/ */
package org.wso2.carbon.device.mgt.core.config; package org.wso2.carbon.device.mgt.core.config;
import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration; import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations; import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
@ -46,6 +47,7 @@ public final class DeviceManagementConfig {
private PullNotificationConfiguration pullNotificationConfiguration; private PullNotificationConfiguration pullNotificationConfiguration;
private DeviceStatusTaskConfig deviceStatusTaskConfig; private DeviceStatusTaskConfig deviceStatusTaskConfig;
private DeviceCacheConfiguration deviceCacheConfiguration; private DeviceCacheConfiguration deviceCacheConfiguration;
private CertificateCacheConfiguration certificateCacheConfiguration;
private GeoLocationConfiguration geoLocationConfiguration; private GeoLocationConfiguration geoLocationConfiguration;
private String defaultGroupsConfiguration; private String defaultGroupsConfiguration;
@ -131,6 +133,15 @@ public final class DeviceManagementConfig {
this.deviceCacheConfiguration = deviceCacheConfiguration; this.deviceCacheConfiguration = deviceCacheConfiguration;
} }
@XmlElement(name = "CertificateCacheConfiguration", required = true)
public CertificateCacheConfiguration getCertificateCacheConfiguration() {
return certificateCacheConfiguration;
}
public void setCertificateCacheConfiguration(CertificateCacheConfiguration certificateCacheConfiguration) {
this.certificateCacheConfiguration = certificateCacheConfiguration;
}
@XmlElement(name = "GeoLocationConfiguration", required = true) @XmlElement(name = "GeoLocationConfiguration", required = true)
public GeoLocationConfiguration getGeoLocationConfiguration() { public GeoLocationConfiguration getGeoLocationConfiguration() {
return geoLocationConfiguration; return geoLocationConfiguration;

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.device.mgt.core.config.cache;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "CertificateCacheConfiguration")
public class CertificateCacheConfiguration {
private boolean isEnabled;
private int expiryTime;
@XmlElement(name = "Enable", required = true)
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean enabled) {
isEnabled = enabled;
}
@XmlElement(name = "ExpiryTime", required = true)
public int getExpiryTime() {
return expiryTime;
}
public void setExpiryTime(int expiryTime) {
this.expiryTime = expiryTime;
}
}

@ -76,7 +76,7 @@ public final class DeviceManagerUtil {
private static final Log log = LogFactory.getLog(DeviceManagerUtil.class); private static final Log log = LogFactory.getLog(DeviceManagerUtil.class);
private static boolean isDeviceCacheInistialized = false; private static boolean isDeviceCacheInitialized = false;
public static Document convertToDocument(File file) throws DeviceManagementException { public static Document convertToDocument(File file) throws DeviceManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@ -494,8 +494,8 @@ public final class DeviceManagerUtil {
int deviceCacheExpiry = config.getDeviceCacheConfiguration().getExpiryTime(); int deviceCacheExpiry = config.getDeviceCacheConfiguration().getExpiryTime();
CacheManager manager = getCacheManager(); CacheManager manager = getCacheManager();
if (config.getDeviceCacheConfiguration().isEnabled()) { if (config.getDeviceCacheConfiguration().isEnabled()) {
if(!isDeviceCacheInistialized) { if(!isDeviceCacheInitialized) {
isDeviceCacheInistialized = true; isDeviceCacheInitialized = true;
if (manager != null) { if (manager != null) {
if (deviceCacheExpiry > 0) { if (deviceCacheExpiry > 0) {
manager.<DeviceCacheKey, Device>createCacheBuilder(DeviceManagementConstants.DEVICE_CACHE). manager.<DeviceCacheKey, Device>createCacheBuilder(DeviceManagementConstants.DEVICE_CACHE).
@ -525,7 +525,7 @@ public final class DeviceManagerUtil {
CacheManager manager = getCacheManager(); CacheManager manager = getCacheManager();
Cache<DeviceCacheKey, Device> deviceCache = null; Cache<DeviceCacheKey, Device> deviceCache = null;
if (config.getDeviceCacheConfiguration().isEnabled()) { if (config.getDeviceCacheConfiguration().isEnabled()) {
if(!isDeviceCacheInistialized) { if(!isDeviceCacheInitialized) {
initializeDeviceCache(); initializeDeviceCache();
} }
if (manager != null) { if (manager != null) {

@ -78,6 +78,10 @@
<Enable>true</Enable> <Enable>true</Enable>
<ExpiryTime>600</ExpiryTime> <ExpiryTime>600</ExpiryTime>
</DeviceCacheConfiguration> </DeviceCacheConfiguration>
<CertificateCacheConfiguration>
<Enable>true</Enable>
<ExpiryTime>86400</ExpiryTime>
</CertificateCacheConfiguration>
<GeoLocationConfiguration> <GeoLocationConfiguration>
<isEnabled>false</isEnabled> <isEnabled>false</isEnabled>
<PublishLocationOperationResponse>false</PublishLocationOperationResponse> <PublishLocationOperationResponse>false</PublishLocationOperationResponse>

Loading…
Cancel
Save