From ab67fbdf5d661a33b67436c70db0dcb8b840cf57 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 31 Mar 2016 08:03:28 +0200 Subject: if database cleanUP process found some unhandled exception, write error messages to technical log --- id/server/auth-final/pom.xml | 2 +- .../moa/id/auth/AuthenticationSessionCleaner.java | 76 +++++++++++++++++++++- .../moa/id/auth/servlet/AbstractController.java | 24 ++++++- .../AbstractProcessEngineSignalController.java | 6 +- .../moa/id/data/ExceptionContainer.java | 65 ++++++++++++++++++ .../protocols/ProtocolFinalizationController.java | 12 ++-- .../moa/id/storage/DBTransactionStorage.java | 37 ++++++----- .../moa/id/storage/ITransactionStorage.java | 15 ++++- .../servlet/SSOTransferSignalServlet.java | 6 +- 9 files changed, 207 insertions(+), 36 deletions(-) create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/ExceptionContainer.java diff --git a/id/server/auth-final/pom.xml b/id/server/auth-final/pom.xml index 776ec00d3..61eba7f22 100644 --- a/id/server/auth-final/pom.xml +++ b/id/server/auth-final/pom.xml @@ -165,7 +165,7 @@ diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java index 94138e0fc..e0552c337 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java @@ -4,15 +4,22 @@ 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.stereotype.Service; +import at.gv.egovernment.moa.id.advancedlogging.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.data.ExceptionContainer; +import at.gv.egovernment.moa.id.process.ProcessExecutionException; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.id.storage.ITransactionStorage; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; /** * Thread cleaning the AuthenticationServer session store @@ -53,11 +60,55 @@ public class AuthenticationSessionCleaner implements Runnable { authenticationSessionStorage.clean(now, sessionTimeOutCreated, sessionTimeOutUpdated); //clean TransactionStorage - transactionStorage.clean(now, authDataTimeOut); + 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 is could be unhandled + if (entry != null && entry instanceof ExceptionContainer) { + ExceptionContainer exContainer = (ExceptionContainer) entry; + + if (exContainer.getExceptionThrown() != null) { + //add session and transaction ID to log if exists + if (MiscUtil.isNotEmpty(exContainer.getUniqueTransactionID())) + TransactionIDUtils.setTransactionId(exContainer.getUniqueTransactionID()); + + if (MiscUtil.isNotEmpty(exContainer.getUniqueSessionID())) + TransactionIDUtils.setSessionId(exContainer.getUniqueSessionID()); + + //log exception to technical log + logExceptionToTechnicalLog(exContainer.getExceptionThrown()); + + //remove session and transaction ID from thread + TransactionIDUtils.removeSessionId(); + TransactionIDUtils.removeTransactionId(); + } + } + + } 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 cleanUp FAILED!" , e); + Logger.error("Session/Transaction cleanUp FAILED!" , e); } @@ -72,6 +123,27 @@ public class AuthenticationSessionCleaner implements Runnable { } } + /** + * 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()); + + } + } + } + /** * start the sessionCleaner */ diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java index e51f3e6c9..fd2e03afa 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.ExceptionHandler; +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; import at.gv.egovernment.moa.id.advancedlogging.StatisticLogger; import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException; @@ -42,10 +43,12 @@ import at.gv.egovernment.moa.id.auth.frontend.exception.GUIBuildException; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.data.ExceptionContainer; import at.gv.egovernment.moa.id.moduls.IRequestStorage; import at.gv.egovernment.moa.id.process.ProcessExecutionException; import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController; @@ -101,8 +104,12 @@ public abstract class AbstractController extends MOAIDAuthConstants { } protected void handleError(String errorMessage, Throwable exceptionThrown, - HttpServletRequest req, HttpServletResponse resp, String pendingRequestID) throws IOException { + HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq) throws IOException { + String pendingRequestID = null; + if (pendingReq != null) + pendingRequestID = pendingReq.getRequestID(); + Throwable loggedException = null; Throwable extractedException = extractOriginalExceptionFromProcessException(exceptionThrown); @@ -127,8 +134,19 @@ public abstract class AbstractController extends MOAIDAuthConstants { //switch to protocol-finalize method to generate a protocol-specific error message //put exception into transaction store for redirect - String key = Random.nextRandom(); - transactionStorage.put(key, loggedException); + String key = Random.nextLongRandom(); + if (pendingReq != null) { + revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR); + transactionStorage.put(key, + new ExceptionContainer(pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), loggedException)); + + } else { + transactionStorage.put(key, + new ExceptionContainer(null, + null, loggedException)); + + } //build up redirect URL String redirectURL = null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractProcessEngineSignalController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractProcessEngineSignalController.java index 7a4ee35fa..0ce7b0050 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractProcessEngineSignalController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractProcessEngineSignalController.java @@ -28,14 +28,14 @@ public abstract class AbstractProcessEngineSignalController extends AbstractCont protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException { String pendingRequestID = StringEscapeUtils.escapeHtml(getPendingRequestId(req)); - + IRequest pendingReq = null; try { if (pendingRequestID == null) { throw new MOAIllegalStateException("process.03", new Object[]{"Unable to determine MOA pending-request id."}); } - IRequest pendingReq = requestStorage.getPendingRequest(pendingRequestID); + pendingReq = requestStorage.getPendingRequest(pendingRequestID); if (pendingReq == null) { Logger.info("No PendingRequest with Id: " + pendingRequestID + " Maybe, a transaction timeout occure."); throw new MOAIDException("auth.28", new Object[]{pendingRequestID}); @@ -60,7 +60,7 @@ public abstract class AbstractProcessEngineSignalController extends AbstractCont processEngine.signal(pendingReq); } catch (Exception ex) { - handleError(null, ex, req, resp, pendingRequestID); + handleError(null, ex, req, resp, pendingReq); } finally { //MOASessionDBUtils.closeSession(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/ExceptionContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/ExceptionContainer.java new file mode 100644 index 000000000..5e3fb5df6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/ExceptionContainer.java @@ -0,0 +1,65 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.data; + +/** + * @author tlenz + * + */ +public class ExceptionContainer { + + private Throwable exceptionThrown = null; + private String uniqueSessionID = null; + private String uniqueTransactionID = null; + + /** + * + */ + public ExceptionContainer(String uniqueSessionID, String uniqueTransactionID, Throwable exception) { + this.uniqueSessionID = uniqueSessionID; + this.uniqueTransactionID = uniqueTransactionID; + this.exceptionThrown = exception; + } + + /** + * @return the exceptionThrown + */ + public Throwable getExceptionThrown() { + return exceptionThrown; + } + /** + * @return the uniqueSessionID + */ + public String getUniqueSessionID() { + return uniqueSessionID; + } + /** + * @return the uniqueTransactionID + */ + public String getUniqueTransactionID() { + return uniqueTransactionID; + } + + + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java index 991c6a881..0da43d818 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java @@ -38,6 +38,7 @@ import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.commons.api.IRequest; 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.data.ExceptionContainer; import at.gv.egovernment.moa.id.util.ParamValidatorUtils; import at.gv.egovernment.moa.logging.Logger; @@ -66,15 +67,14 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon if (errorid != null) { try { //load stored exception from database - Throwable throwable = transactionStorage.get(errorid, Throwable.class); - - if (throwable != null) { + ExceptionContainer container = transactionStorage.get(errorid, ExceptionContainer.class); + if (container != null) { //remove exception if it was found transactionStorage.remove(errorid); - if (pendingReq != null) { - revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR); - + Throwable throwable = container.getExceptionThrown(); + + if (pendingReq != null) { //build protocol-specific error message if possible buildProtocolSpecificErrorResponse(throwable, req, resp, pendingReq); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java index ff631a720..6778dc32e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java @@ -23,6 +23,7 @@ package at.gv.egovernment.moa.id.storage; import java.io.Serializable; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -99,6 +100,17 @@ public class DBTransactionStorage implements ITransactionStorage { } } + public Object get(String key) throws MOADatabaseException { + AssertionStore element = searchInDatabase(key); + + if (element == null) + return null; + + return SerializationUtils.deserialize(element.getAssertion()); + + + } + public T get(String key, final Class clazz, long dataTimeOut) throws MOADatabaseException, AuthenticationException { AssertionStore element = searchInDatabase(key); @@ -134,10 +146,11 @@ public class DBTransactionStorage implements ITransactionStorage { } } - public void clean(Date now, long dataTimeOut) { + public List clean(Date now, long dataTimeOut) { Date expioredate = new Date(now.getTime() - dataTimeOut); List results; + List returnValues = new ArrayList();; Session session = MOASessionDBUtils.getCurrentSession(); synchronized (session) { @@ -146,22 +159,14 @@ public class DBTransactionStorage implements ITransactionStorage { query.setTimestamp("timeout", expioredate); results = query.list(); session.getTransaction().commit(); - - if (results.size() != 0) { - for(AssertionStore result : results) { - try { - cleanDelete(result); - Logger.info("Remove stored information with ID: " + result.getArtifact() - + " after timeout."); - - } catch (HibernateException e){ - Logger.warn("Sessioninformation with ID=" + result.getArtifact() - + " not removed after timeout! (Error during Database communication)", e); - } - - } - } } + + if (results != null) { + for (AssertionStore el : results) + returnValues.add(el.getArtifact()); + + } + return returnValues; } public void remove(String key) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java index 48283d2b6..fe959c39d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java @@ -23,6 +23,7 @@ package at.gv.egovernment.moa.id.storage; import java.util.Date; +import java.util.List; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; @@ -50,6 +51,15 @@ public interface ITransactionStorage { */ public void put(String key, Object value) throws MOADatabaseException; + /** + * Get a data object from transaction storage + * + * @param key key Id which identifiers the data object + * @return The transaction-data object, or null + * @throws MOADatabaseException In case of load operation failed + */ + public Object get(String key) throws MOADatabaseException; + /** * Get a data object from transaction storage * @@ -91,11 +101,12 @@ public interface ITransactionStorage { public void remove(String key); /** - * Clean-up the transaction storage + * Get all entries for Clean-up the transaction storage * * @param now Current time * @param dataTimeOut Data-object timeout in [ms] + * @return List of entry-keys which as a timeout */ - public void clean(Date now, long dataTimeOut); + public List clean(Date now, long dataTimeOut); } diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java index cd18afb71..e92925dfb 100644 --- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java +++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferSignalServlet.java @@ -61,13 +61,13 @@ public class SSOTransferSignalServlet extends AbstractProcessEngineSignalControl @Override protected void signalProcessManagement(HttpServletRequest req, HttpServletResponse resp) throws IOException { String pendingRequestID = StringEscapeUtils.escapeHtml(getPendingRequestId(req)); - + IRequest pendingReq = null; try { if (pendingRequestID == null) { throw new IllegalStateException("Unable to determine MOA pending-request id."); } - IRequest pendingReq = requestStorage.getPendingRequest(pendingRequestID); + pendingReq = requestStorage.getPendingRequest(pendingRequestID); if (pendingReq == null) { Logger.info("No PendingRequest with Id: " + pendingRequestID + " Maybe, a transaction timeout occure."); throw new MOAIDException("auth.28", new Object[]{pendingRequestID}); @@ -87,7 +87,7 @@ public class SSOTransferSignalServlet extends AbstractProcessEngineSignalControl processEngine.signal(pendingReq); } catch (Exception ex) { - handleError(null, ex, req, resp, pendingRequestID); + handleError(null, ex, req, resp, pendingReq); } finally { //MOASessionDBUtils.closeSession(); -- cgit v1.2.3