From 173b6db7d9ed8c1115ec634de68b7a9d8f70f812 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 3 Oct 2013 12:10:05 +0200 Subject: add DBExceptionStoreImpl to store Exceptions in DB instead of in a HashMap --- .../moa/id/auth/servlet/AuthServlet.java | 51 +++---- .../id/config/auth/AuthConfigurationProvider.java | 2 + .../moa/id/entrypoints/DispatcherServlet.java | 98 ++++++------- .../moa/id/storage/DBExceptionStoreImpl.java | 153 +++++++++++++++++++++ .../id/commons/db/dao/session/ExceptionStore.java | 103 ++++++++++++++ .../resources/config/hibernate_moasession.cfg.xml | 1 + 6 files changed, 317 insertions(+), 91 deletions(-) create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java create mode 100644 id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/ExceptionStore.java (limited to 'id') diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java index 0e4f72248..517fff9d2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java @@ -52,6 +52,7 @@ import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.entrypoints.DispatcherServlet; +import at.gv.egovernment.moa.id.storage.DBExceptionStoreImpl; import at.gv.egovernment.moa.id.storage.ExceptionStoreImpl; import at.gv.egovernment.moa.id.storage.IExceptionStore; import at.gv.egovernment.moa.id.util.ServletUtils; @@ -168,46 +169,30 @@ public class AuthServlet extends HttpServlet implements MOAIDAuthConstants { req.setAttribute("LogLevel", "debug"); } - IExceptionStore store = ExceptionStoreImpl.getStore(); + IExceptionStore store = DBExceptionStoreImpl.getStore(); String id = store.storeException(exceptionThrown); - String redirectURL = null; + if (id != null) { + + String redirectURL = null; - redirectURL = ServletUtils.getBaseUrl(req); - redirectURL += "/dispatcher?" + ERROR_CODE_PARAM + "=" + id - + "&" + DispatcherServlet.PARAM_TARGET_PENDINGREQUESTID + "=" + pendingRequestID; + redirectURL = ServletUtils.getBaseUrl(req); + redirectURL += "/dispatcher?" + ERROR_CODE_PARAM + "=" + id + + "&" + DispatcherServlet.PARAM_TARGET_PENDINGREQUESTID + "=" + pendingRequestID; - resp.setContentType("text/html"); - resp.setStatus(302); + resp.setContentType("text/html"); + resp.setStatus(302); - resp.addHeader("Location", redirectURL); - Logger.debug("REDIRECT TO: " + redirectURL); + resp.addHeader("Location", redirectURL); + Logger.debug("REDIRECT TO: " + redirectURL); - return; - /* - // forward this to errorpage-auth.jsp where the HTML error page is - // generated - ServletContext context = getServletContext(); - RequestDispatcher dispatcher = context - .getRequestDispatcher("/errorpage-auth.jsp"); - try { - - resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES, - MOAIDAuthConstants.HEADER_VALUE_EXPIRES); - resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA, - MOAIDAuthConstants.HEADER_VALUE_PRAGMA); - resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL, - MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL); - resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL, - MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE); - - dispatcher.forward(req, resp); - } catch (ServletException e) { - Logger.error(e); - } catch (IOException e) { - Logger.error(e); + return; + + } else { + + //Exception can not be stored in database + handleErrorNoRedirect(errorMessage, exceptionThrown, req, resp); } - */ } /** diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java index 81ee988e3..31acee7ba 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java @@ -72,6 +72,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.VerifyAuthBlock; import at.gv.egovernment.moa.id.commons.db.dao.config.VerifyIdentityLink; import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore; +import at.gv.egovernment.moa.id.commons.db.dao.session.ExceptionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OldSSOSessionIDStore; import at.gv.egovernment.moa.id.commons.db.dao.statistic.StatisticLog; @@ -309,6 +310,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider { config.addAnnotatedClass(AuthenticatedSessionStore.class); config.addAnnotatedClass(OASessionStore.class); config.addAnnotatedClass(OldSSOSessionIDStore.class); + config.addAnnotatedClass(ExceptionStore.class); config.addProperties(moaSessionProp); MOASessionDBUtils.initHibernate(config, moaSessionProp); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java index 0badebdbb..d4e08318d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java @@ -3,10 +3,7 @@ package at.gv.egovernment.moa.id.entrypoints; import java.io.IOException; -import java.util.ConcurrentModificationException; -import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -16,7 +13,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import javax.swing.ListModel; import at.gv.egovernment.moa.id.advancedlogging.StatisticLogger; import at.gv.egovernment.moa.id.auth.MOAIDAuthInitializer; @@ -37,8 +33,8 @@ import at.gv.egovernment.moa.id.moduls.NoPassivAuthenticationException; import at.gv.egovernment.moa.id.moduls.RequestStorage; import at.gv.egovernment.moa.id.moduls.SSOManager; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.storage.DBExceptionStoreImpl; import at.gv.egovernment.moa.id.storage.ExceptionStoreImpl; -import at.gv.egovernment.moa.id.util.HTTPSessionUtils; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.legacy.LegacyHelper; @@ -86,9 +82,9 @@ public class DispatcherServlet extends AuthServlet{ String errorid = req.getParameter(ERROR_CODE_PARAM); if (errorid != null) { - Throwable throwable = ExceptionStoreImpl.getStore() + Throwable throwable = DBExceptionStoreImpl.getStore() .fetchException(errorid); - ExceptionStoreImpl.getStore().removeException(errorid); + DBExceptionStoreImpl.getStore().removeException(errorid); Object idObject = req.getParameter(PARAM_TARGET_PENDINGREQUESTID); @@ -236,35 +232,26 @@ public class DispatcherServlet extends AuthServlet{ Object idObject = req.getParameter(PARAM_TARGET_PENDINGREQUESTID); if (protocolRequests != null && - idObject != null && (idObject instanceof String)) { + idObject != null && (idObject instanceof String)) { + + protocolRequestID = (String) idObject; -// synchronized (protocolRequests) { - - protocolRequestID = (String) idObject; - - //get IRequest if it exits - if (protocolRequests.containsKey(protocolRequestID)) { - protocolRequest = protocolRequests.get(protocolRequestID); - - - - Logger.debug(DispatcherServlet.class.getName()+": Found PendingRequest with ID " + protocolRequestID); - - //RequestStorage.setPendingRequest(httpSession, protocolRequests); + //get IRequest if it exits + if (protocolRequests.containsKey(protocolRequestID)) { + protocolRequest = protocolRequests.get(protocolRequestID); + Logger.debug(DispatcherServlet.class.getName()+": Found PendingRequest with ID " + protocolRequestID); - } else { - Logger.error("No PendingRequest with ID " + protocolRequestID + " found.!"); + } else { + Logger.error("No PendingRequest with ID " + protocolRequestID + " found.!"); - Set mapkeys = protocolRequests.keySet(); - for (String el : mapkeys) - Logger.debug("PendingRequest| ID=" + el + " OAIdentifier=" + protocolRequests.get(el)); - - handleErrorNoRedirect("Während des Anmeldevorgangs ist ein Fehler aufgetreten. Bitte versuchen Sie es noch einmal.", - null, req, resp); - //resp.sendError(HttpServletResponse.SC_CONFLICT); - return; - } -// } + Set mapkeys = protocolRequests.keySet(); + for (String el : mapkeys) + Logger.debug("PendingRequest| ID=" + el + " OAIdentifier=" + protocolRequests.get(el)); + + handleErrorNoRedirect("Während des Anmeldevorgangs ist ein Fehler aufgetreten. Bitte versuchen Sie es noch einmal.", + null, req, resp); + return; + } } else { try { protocolRequest = info.preProcess(req, resp, action); @@ -273,26 +260,22 @@ public class DispatcherServlet extends AuthServlet{ if(protocolRequests != null) { -// synchronized (protocolRequests) { -// synchronized (protocolRequest) { - Set mapkeys = protocolRequests.keySet(); - for (String el : mapkeys) { - IRequest value = protocolRequests.get(el); + Set mapkeys = protocolRequests.keySet(); + for (String el : mapkeys) { + IRequest value = protocolRequests.get(el); + + if (value.getOAURL().equals(protocolRequest.getOAURL())) { - if (value.getOAURL().equals(protocolRequest.getOAURL())) { - - if(!AuthenticationSessionStoreage.deleteSessionWithPendingRequestID(el)) { - Logger.warn(DispatcherServlet.class.getName()+": NO MOASession with PendingRequestID " + el + " found. Delete all user sessions!"); - RequestStorage.removeAllPendingRequests(req.getSession()); - - } else { - RequestStorage.removePendingRequest(protocolRequests, el); - } - } + if(!AuthenticationSessionStoreage.deleteSessionWithPendingRequestID(el)) { + Logger.warn(DispatcherServlet.class.getName()+": NO MOASession with PendingRequestID " + el + " found. Delete all user sessions!"); + RequestStorage.removeAllPendingRequests(req.getSession()); + + } else { + RequestStorage.removePendingRequest(protocolRequests, el); } -// } -// } - + } + } + } else { protocolRequests = new ConcurrentHashMap(); } @@ -311,19 +294,22 @@ public class DispatcherServlet extends AuthServlet{ } } } catch (MOAIDException e) { - resp.sendError(HttpServletResponse.SC_BAD_REQUEST); Logger.error("Failed to generate a valid protocol request!"); + resp.sendError(HttpServletResponse.SC_BAD_REQUEST); + resp.setContentType("text/html;charset=UTF-8"); + resp.getWriter().write("NO valid protocol request received!"); return; } if (protocolRequest == null) { - resp.sendError(HttpServletResponse.SC_BAD_REQUEST); Logger.error("Failed to generate a valid protocol request!"); + resp.sendError(HttpServletResponse.SC_BAD_REQUEST); + resp.setContentType("text/html;charset=UTF-8"); + resp.getWriter().write("NO valid protocol request received!"); return; } } - RequestStorage.setPendingRequest(httpSession, protocolRequests); AuthenticationManager authmanager = AuthenticationManager.getInstance(); @@ -403,7 +389,6 @@ public class DispatcherServlet extends AuthServlet{ if ((useSSOOA || isValidSSOSession)) //TODO: SSO with mandates requires an OVS extension { - //TODO SSO Question!!!! if (useSSOOA && isValidSSOSession) { moasessionID = ssomanager.getMOASession(ssoId); @@ -433,8 +418,6 @@ public class DispatcherServlet extends AuthServlet{ } } else { -// moasessionID = HTTPSessionUtils.getHTTPSessionString(req.getSession(), -// AuthenticationManager.MOA_SESSION, null); moasessionID = (String) req.getParameter(PARAM_SESSIONID); @@ -451,7 +434,6 @@ public class DispatcherServlet extends AuthServlet{ RequestStorage.removePendingRequest(protocolRequests, protocolRequestID); if (needAuthentication) { - //boolean isSSOSession = AuthenticationSessionStoreage.isSSOSession(moasessionID); boolean isSSOSession = MiscUtil.isNotEmpty(newSSOSessionId); if ((useSSOOA || isSSOSession) //TODO: SSO with mandates requires an OVS extension diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java new file mode 100644 index 000000000..13919a13c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java @@ -0,0 +1,153 @@ +package at.gv.egovernment.moa.id.storage; + +import java.util.Date; +import java.util.List; + +import org.apache.commons.lang.SerializationUtils; +import org.hibernate.HibernateException; +import org.hibernate.Query; +import org.hibernate.Session; + +import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; +import at.gv.egovernment.moa.id.commons.db.dao.session.ExceptionStore; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +public class DBExceptionStoreImpl implements IExceptionStore { + + private static DBExceptionStoreImpl store; + + public static DBExceptionStoreImpl getStore() { + if(store == null) { + store = new DBExceptionStoreImpl(); + } + return store; + } + + public String storeException(Throwable e) { + String id = Random.nextRandom(); + + Logger.debug("Store Exception with ID " + id); + + ExceptionStore dbexception = new ExceptionStore(); + dbexception.setExid(id); + + byte[] data = SerializationUtils.serialize(e); + dbexception.setException(data); + + dbexception.setTimestamp(new Date()); + + try { + MOASessionDBUtils.saveOrUpdate(dbexception); + + } catch (MOADatabaseException e1) { + Logger.warn("Exception can not be stored in Database.", e); + return null; + } + + return id; + } + + public Throwable fetchException(String id) { + + try { + Logger.debug("Fetch Exception with ID " + id); + + ExceptionStore ex = searchInDatabase(id); + + Object data = SerializationUtils.deserialize(ex.getException()); + if (data instanceof Throwable) + return (Throwable) data; + + else { + Logger.warn("Exeption is not of classtype Throwable"); + return null; + } + + + } catch (MOADatabaseException e) { + Logger.info("No Exception found with ID=" + id); + return null; + + } catch (Exception e) { + Logger.warn("Exception can not deserialized from Database.",e); + return null; + } + + } + + public void removeException(String id) { + try { + ExceptionStore ex = searchInDatabase(id); + MOASessionDBUtils.delete(ex); + + Logger.debug("Delete Execption with ID " + id); + + } catch (MOADatabaseException e) { + Logger.info("No Exception found with ID=" + id); + } + + + } + + public void clean(long now, long exceptionTimeOut) { + Date expioredate = new Date(now - exceptionTimeOut); + + List results; + Session session = MOASessionDBUtils.getCurrentSession(); + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getExceptionWithTimeOut"); + query.setTimestamp("timeout", expioredate); + results = query.list(); + session.getTransaction().commit(); + } + + if (results.size() != 0) { + for(ExceptionStore result : results) { + try { + MOASessionDBUtils.delete(result); + Logger.info("Remove Exception with ID=" + result.getExid() + + " after timeout."); + + } catch (HibernateException e){ + Logger.warn("Exception with ID=" + result.getExid() + + " not removed after timeout! (Error during Database communication)", e); + } + + } + } + } + + @SuppressWarnings("rawtypes") + private ExceptionStore searchInDatabase(String id) throws MOADatabaseException { + MiscUtil.assertNotNull(id, "exceptionID"); + Logger.trace("Getting Exception with ID " + id + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getExceptionWithID"); + query.setString("id", id); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() != 1) { + Logger.trace("No entries found."); + throw new MOADatabaseException("No Exception found with ID " + id); + } + + return (ExceptionStore) result.get(0); + } + +} diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/ExceptionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/ExceptionStore.java new file mode 100644 index 000000000..c439cdb64 --- /dev/null +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/ExceptionStore.java @@ -0,0 +1,103 @@ +package at.gv.egovernment.moa.id.commons.db.dao.session; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; + +import org.hibernate.annotations.DynamicUpdate; + + + +@Entity +@DynamicUpdate(value=true) +@Table(name = "exceptionstore") +@NamedQueries({ + @NamedQuery(name="getExceptionWithID", query = "select exceptionstore from ExceptionStore exceptionstore where exceptionstore.exid = :id"), + @NamedQuery(name="getExceptionWithTimeOut", query = "select exceptionstore from ExceptionStore exceptionstore where exceptionstore.timestamp < :timeout") +}) + +public class ExceptionStore implements Serializable{ + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", unique=true, nullable=false) + private long id; + + @Column(name = "exid", unique=true, nullable=false) + private String exid; + + @Column(name = "exception", nullable=false) + @Lob private byte [] exception; + + @Column(name = "timestamp", nullable=false) + private Date timestamp; + + /** + * @return the id + */ + public long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(long id) { + this.id = id; + } + + /** + * @return the exid + */ + public String getExid() { + return exid; + } + + /** + * @param exid the exid to set + */ + public void setExid(String exid) { + this.exid = exid; + } + + /** + * @return the exception + */ + public byte[] getException() { + return exception; + } + + /** + * @param exception the exception to set + */ + public void setException(byte[] exception) { + this.exception = exception; + } + + /** + * @return the timestamp + */ + public Date getTimestamp() { + return timestamp; + } + + /** + * @param timestamp the timestamp to set + */ + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + +} diff --git a/id/server/moa-id-commons/src/main/resources/config/hibernate_moasession.cfg.xml b/id/server/moa-id-commons/src/main/resources/config/hibernate_moasession.cfg.xml index 4841481b6..e40c8b8a9 100644 --- a/id/server/moa-id-commons/src/main/resources/config/hibernate_moasession.cfg.xml +++ b/id/server/moa-id-commons/src/main/resources/config/hibernate_moasession.cfg.xml @@ -10,5 +10,6 @@ + \ No newline at end of file -- cgit v1.2.3