Page 1 of 1

LdapPrincipalAdapter and Directory Listing

PostPosted:Wed Apr 22, 2015 8:14 am
by Catscratch
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:
Code: Select all
Cache cache = null;
LdapPrincipalAdapter.getName(String user):
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;
        }
}

Re: LdapPrincipalAdapter and Directory Listing

PostPosted:Thu Apr 23, 2015 11:19 am
by jllort
You will need this workaroung because on community version we've not implemented cache system, in only available on professional. On professional are cached several things to solve this king of problems, but these optimizations are still not present on community version.

Re: LdapPrincipalAdapter and Directory Listing

PostPosted:Thu Apr 23, 2015 11:47 am
by Catscratch
Ok. Any chance to get such things back into community version? Or may the community push features (like this caching mechanism) back to the repository?

Re: LdapPrincipalAdapter and Directory Listing

PostPosted:Sat Apr 25, 2015 8:08 am
by jllort
Us we make periodically upgrades to community. At the present is not planned release cache features on community. Anyway if a community user works on it and provide us a patch we will include into OpenKM community source code.