package org.apereo.cas.audit.spi;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.apereo.cas.support.events.audit.CasAuditActionContextRecordedEvent;
import org.apereo.cas.util.ISOStandardDateFormat;
import org.apereo.inspektr.audit.AuditActionContext;
import org.apereo.inspektr.audit.AuditTrailManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* This is {@link DefaultDelegatingAuditTrailManager}.
*
* @author Misagh Moayyed
* @since 5.0.0
*/
public class DefaultDelegatingAuditTrailManager implements DelegatingAuditTrailManager {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDelegatingAuditTrailManager.class);
private static final int INITIAL_CACHE_SIZE = 50;
private static final long MAX_CACHE_SIZE = 1000;
@Autowired
private ApplicationEventPublisher eventPublisher;
private final AuditTrailManager manager;
private final LoadingCache<String, AuditActionContext> storage;
private int expirationDuration = 2;
private TimeUnit expirationTimeUnit = TimeUnit.HOURS;
public DefaultDelegatingAuditTrailManager(final AuditTrailManager manager) {
this.manager = manager;
this.storage = CacheBuilder.newBuilder()
.initialCapacity(INITIAL_CACHE_SIZE)
.maximumSize(MAX_CACHE_SIZE)
.recordStats()
.expireAfterWrite(this.expirationDuration, this.expirationTimeUnit)
.build(new CacheLoader<String, AuditActionContext>() {
@Override
public AuditActionContext load(final String s) throws Exception {
LOGGER.error("Load operation of the audit cache is not supported.");
return null;
}
});
}
@Override
public void record(final AuditActionContext auditActionContext) {
this.manager.record(auditActionContext);
final String key = new StringBuilder(auditActionContext.getPrincipal())
.append("@").append(auditActionContext.getActionPerformed())
.append("@").append(auditActionContext.getResourceOperatedUpon())
.append("@").append(ISOStandardDateFormat.getInstance().format(auditActionContext.getWhenActionWasPerformed()))
.toString();
this.storage.put(key, auditActionContext);
if (this.eventPublisher != null) {
this.eventPublisher.publishEvent(new CasAuditActionContextRecordedEvent(this, auditActionContext));
}
}
@Override
public Set<AuditActionContext> get() {
return new HashSet<>(this.storage.asMap().values());
}
public void setExpirationDuration(final int expirationDuration) {
this.expirationDuration = expirationDuration;
}
public void setExpirationTimeUnit(final TimeUnit expirationTimeUnit) {
this.expirationTimeUnit = expirationTimeUnit;
}
}