Hi,
I noticed a strange performance problem when using LDAP with OpenKM. When listing directory with e.g. 300 documents, the listing itself is very fast in a non-ldap environment. However, when using ldap the listing is taking a while which makes working with OpenKM nearly impossible.
Through trace logging I saw, that there is a ldap query for EACH document in the list. In detail, the LdapPrincipalAdapter.getName(String user) is called 300 times for the same user (the user who triggered the directory listing). The query itself doesn't took so long (about 50ms), but in total we got 300*50ms plus other overheads. Which makes 15.000 ms + X.
So my question is, is there a way to improve this? Does OpenKM got some kind of improvement I may activate?
Right know I build a workaround and integrated an EHCache into LdapPrincipalAdapter which puts the requesting user into a cache and deliveries information from there. The cache element got a timeout of 2 minutes. This workaround improved the performance 300 times for 300 elements. So overall it's a performance improvement of N times number of documents that are listed.
I wonder if there is already a mechanism I can use so that I don't need this workaround.
Anyway, for completeness here is the small code extension:
LdapPrincipialAdapter - private fields:
I noticed a strange performance problem when using LDAP with OpenKM. When listing directory with e.g. 300 documents, the listing itself is very fast in a non-ldap environment. However, when using ldap the listing is taking a while which makes working with OpenKM nearly impossible.
Through trace logging I saw, that there is a ldap query for EACH document in the list. In detail, the LdapPrincipalAdapter.getName(String user) is called 300 times for the same user (the user who triggered the directory listing). The query itself doesn't took so long (about 50ms), but in total we got 300*50ms plus other overheads. Which makes 15.000 ms + X.
So my question is, is there a way to improve this? Does OpenKM got some kind of improvement I may activate?
Right know I build a workaround and integrated an EHCache into LdapPrincipalAdapter which puts the requesting user into a cache and deliveries information from there. The cache element got a timeout of 2 minutes. This workaround improved the performance 300 times for 300 elements. So overall it's a performance improvement of N times number of documents that are listed.
I wonder if there is already a mechanism I can use so that I don't need this workaround.
Anyway, for completeness here is the small code extension:
LdapPrincipialAdapter - private fields:
Code: Select all
LdapPrincipalAdapter.getName(String user):
Cache cache = null;
Code: Select all
@Override
public String getName(String user) throws PrincipalAdapterException {
log.debug("getName({})", user);
long begin = System.currentTimeMillis();
String name = null;
if(cache == null) {
CacheConfiguration config = new CacheConfiguration("ldapWorkaroundCache", 1000).timeToLiveSeconds(120).eternal(false);
cache = new Cache(config);
CacheManager.getInstance().addCache(cache);
}
if(user != null && cache.get(user) != null && !cache.get(user).isExpired()) {
if(cache.get(user).getObjectValue() != null)
return cache.get(user).getObjectValue().toString();
else
return null;
} else {
// @formatter:off
List<String> ldap = ldapSearch(MessageFormat.format(Config.PRINCIPAL_LDAP_USERNAME_SEARCH_BASE, user),
MessageFormat.format(Config.PRINCIPAL_LDAP_USERNAME_SEARCH_FILTER, user),
Config.PRINCIPAL_LDAP_USERNAME_ATTRIBUTE);
// @formatter:on
if (!ldap.isEmpty()) {
name = ldap.get(0);
}
log.trace("getName.Time: {}", System.currentTimeMillis() - begin);
log.debug("getName: {}", name);
cache.put(new Element(user, name));
return name;
}
}
