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()); } } } }