[bug_report] Cached LDAP group information is never updated

Note; This is an issue with the hazelcast.jar clustering; the older/legacy coherence based clustering.jar does not have this issue.

Steps to reproduce;

  1. With a hazelcast clustered Openfire backed by LDAP, access the User/Groups -> Groups screen, and select a group. Note the members of that group.

  2. Update the back-end LDAP, and add a new user to the group identified above.

  3. Wait 15 minutes.

  4. Check the members of the group again.

Expected results;
The user added to the group is displayed.

Actual results;

The user is not displayed in the group.

Quick analysis;

In the clustering.jar plugin, the class com.jivesoftware.util.cache.ClusteredCache extends com.tangosol.net.cache.LocalCache which extends com.tangosol.net.cache.OldCache This underlying OldCache class has code present that will evict members from the cache after they have been present for a period of time; for the LDAP groups, this defaults to 15 minutes (the value of back-expiry in the “Group Metadata Cache” entry in coherence-cache-config.xml) - so with clustering.jar 15 minutes after the member is added to the group, Openfire is aware of it.

In hazelcast.jar, the class com.jivesoftware.util.cache.ClusteredCache uses a com.hazelcast.core.IMap to hold the clustered data. This is configured in hazelcast-cache-config.xml - which does not specify a tag (ref: 2.3. Distributed Map), so the entries live forever (or until the cache is full).

Note 1; in the section of hazelcast-cache-config.xml tagged , none of the entries have a TTL. I believe the following tags should be added based on the values in the file coherence-cache-config.xml:

Group Metadata Cache: 900

Group: 900

Roster: 21600

User: 1800

Note 2; whilst checking out the details of this issue, I spotted an error in the hazelcast implementation of com.jivesoftware.util.cache.ClusteredCache; lines 162->164 currently read;

public void setMaxLifetime(long maxLifetime) {

CacheFactory.setMaxSizeProperty(getName(), maxLifetime);

}

but should read;

public void setMaxLifetime(long maxLifetime) {

CacheFactory.setMaxLifetimeProperty(getName(), maxLifetime);

}

(it’s the lifetime of the cache that should be set, not the size).

Excellent analysis, and the fix looks good as well … good catch. Thanks for your contribution!