cas 3.5.2.1 ehcache replication issues

8 views
Skip to first unread message

Ray Bon

unread,
Jul 13, 2016, 11:34:28 AM7/13/16
to CAS Community
We are running cas 3.5.2.1 with ehcache 2.6.0.
I have created a custom ticket expiration listener (implements
net.sf.ehcache.event.CacheEventListener) to 1) prevent tickets from
expiring if user selects 'remember me' and 2) send logout to services
when ticket expires.

Testing in development and preprod environments shows this solution
works. However in production we have experienced runaway tomcat thread
creation which quickly leads to tomcat becoming unresponsive.

At the logging level we have in production, there is no indication of
the [source of the] problem. We believe the problem is triggered by the
custom listener when it updates the remote caches, perhaps a race condition.

So the question: is this the way to mange ticket expiration when using
ehcache with cas or is there a another option?

Ray

P.S. below is the custom code. The only working method is
notifyElementExpired. If the user has selected 'remember me' and the max
lifetime has not been reached then put the ticket back in the cache
otherwise tell TGT to logout of services.


package ca.uvic.idm.cas.ehcache.event;

import net.sf.ehcache.event.CacheEventListener;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;

import org.jasig.cas.ticket.TicketGrantingTicketImpl;
import org.jasig.cas.ticket.ExpirationPolicy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TicketExpirationListener implements CacheEventListener {

private final Logger log = LoggerFactory.getLogger(getClass());
private boolean logUserOutOfServices = true;
@Override
public Object clone() {
return new TicketExpirationListener();
}
@Override
public void dispose() {
}
@Override
public void notifyElementEvicted(Ehcache cache, Element element) {
}
@Override
public void notifyElementExpired(Ehcache cache, Element element) {
log.debug("notifyElementExpired " + cache.getGuid());
log.trace("notifyElementExpired: [cache: " + cache + "; element:
" + element + "]");
Object ticket = element.getObjectValue();
if (ticket instanceof TicketGrantingTicketImpl) {
TicketGrantingTicketImpl tgt = (TicketGrantingTicketImpl)ticket;
if (tgt.isExpired()) {
if (logUserOutOfServices) {
// expire ticket to initiate logout request
tgt.expire();
}
// evict this ticket from other caches
// rather than waiting for them to do it in 30 to 90 s
cache.remove(tgt.getId());
} else {
log.debug("ticket not expired in cas:");
// reset statistics
// put in this cache, update in remote caches
cache.put(element, false);
}
}
}
@Override
public void notifyElementPut(Ehcache cache, Element element) {
}
@Override
public void notifyElementRemoved(Ehcache cache, Element element) {
}
@Override
public void notifyElementUpdated(Ehcache cache, Element element) {
}
@Override
public void notifyRemoveAll(Ehcache cache) {
}
/**
* Whether to log user out of services when a ticket expires.
* Default is true. Set to false to disable.
* @param logUserOutOfServices whether to log user out of services
or not.
*/
public void setLogUserOutOfServices(final boolean
logUserOutOfServices) {
this.logUserOutOfServices = logUserOutOfServices;
}
}
Reply all
Reply to author
Forward
0 new messages