package at.gv.egovernment.moa.id.auth;
import java.util.Date;
import java.util.List;
import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
import at.gv.egovernment.moa.id.commons.api.AuthConfiguration;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
/**
* Thread cleaning the AuthenticationServer
session store
* and authentication data store from garbage.
*
* @author Paul Ivancsics
* @version $Id$
*/
@Service("AuthenticationSessionCleaner")
@EnableScheduling
public class AuthenticationSessionCleaner implements Runnable {
@Autowired private IAuthenticationSessionStoreage authenticationSessionStorage;
@Autowired private ITransactionStorage transactionStorage;
@Autowired protected AuthConfiguration authConfig;
/** interval the AuthenticationSessionCleaner
is run in */
private static final long SESSION_CLEANUP_INTERVAL = 5 * 60 *1000 ; // 5 min
/**
* Runs the thread. Cleans the AuthenticationServer
session store
* and authentication data store from garbage, then sleeps for given interval, and restarts.
*
* Cleans up expired session and authentication data stores.
*
*/
@Scheduled(fixedRate = SESSION_CLEANUP_INTERVAL)
public void run() {
try {
Logger.debug("AuthenticationSessionCleaner run");
Date now = new Date();
try {
int sessionTimeOutCreated = authConfig.getSSOCreatedTimeOut() * 1000;
int sessionTimeOutUpdated = authConfig.getSSOUpdatedTimeOut() * 1000;
int authDataTimeOut = authConfig.getTransactionTimeOut() * 1000;
//clean AuthenticationSessionStore
authenticationSessionStorage.clean(now, sessionTimeOutCreated, sessionTimeOutUpdated);
//clean TransactionStorage
List entryKeysToClean = transactionStorage.clean(now, authDataTimeOut);
if (entryKeysToClean != null && entryKeysToClean.size() != 0) {
for(String entryKey : entryKeysToClean) {
try {
try {
Object entry = transactionStorage.get(entryKey);
//if entry is an exception --> log it because it could be unhandled
if (entry != null && entry instanceof ExceptionContainer) {
ExceptionContainer exContainer = (ExceptionContainer) entry;
if (exContainer.getExceptionThrown() != null) {
//add session, transaction, and service-provider IDs into logging context if exists
if (MiscUtil.isNotEmpty(exContainer.getUniqueTransactionID()))
TransactionIDUtils.setTransactionId(exContainer.getUniqueTransactionID());
if (MiscUtil.isNotEmpty(exContainer.getUniqueSessionID()))
TransactionIDUtils.setSessionId(exContainer.getUniqueSessionID());
if (MiscUtil.isNotEmpty(exContainer.getUniqueServiceProviderId()))
TransactionIDUtils.setServiceProviderId(exContainer.getUniqueServiceProviderId());
//log exception to technical log
logExceptionToTechnicalLog(exContainer.getExceptionThrown());
//remove session and transaction ID from thread
TransactionIDUtils.removeAllLoggingVariables();
} else {
Logger.warn("Receive an ExceptionContainer that includes no 'Exception' object. Somethinge is suspect!!!!!");
}
}
} catch (Exception e) {
Logger.info("Transaction info is not loadable. "
+ "Key:" + entryKey
+ " ErrorMsg:" + e.getMessage());
}
transactionStorage.remove(entryKey);
Logger.info("Remove stored information with ID: " + entryKey
+ " after timeout.");
} catch (HibernateException e){
Logger.warn("Transaction information with ID=" + entryKey
+ " not removed after timeout! (Error during Database communication)", e);
}
}
}
} catch (Exception e) {
Logger.error("Session/Transaction cleanUp FAILED!" , e);
}
} catch (Exception e) {
Logger.error(MOAIDMessageProvider.getInstance().getMessage("cleaner.01", null), e);
}
}
/**
* Write a Exception to the MOA-ID-Auth internal technical log
*
* @param loggedException Exception to log
*/
protected void logExceptionToTechnicalLog(Throwable loggedException) {
if (!( loggedException instanceof MOAIDException
|| loggedException instanceof ProcessExecutionException )) {
Logger.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
} else {
if (Logger.isDebugEnabled() || Logger.isTraceEnabled()) {
Logger.warn(loggedException.getMessage(), loggedException);
} else {
Logger.info(loggedException.getMessage());
}
}
}
}