From 8547f9270a761363d6dd672e7a6104fb1a562eea Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Wed, 6 Dec 2023 17:33:56 +0100 Subject: [PATCH] SSDM-14210 : Deadlock between DefaultSessionManager and PATSessionManagerDecorator --- .../authentication/DefaultSessionManager.java | 16 ++++++++-------- .../cisd/authentication/SessionManagerLock.java | 13 +++++++++++++ .../generic/server/OpenBisSessionManager.java | 3 ++- ...ccessTokenOpenBisSessionManagerDecorator.java | 13 +++++++------ 4 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 lib-authentication/source/java/ch/systemsx/cisd/authentication/SessionManagerLock.java diff --git a/lib-authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java b/lib-authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java index 8005237900d..db7cac6b7eb 100644 --- a/lib-authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java +++ b/lib-authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java @@ -214,7 +214,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa { final String sessionToken = SessionTokenHash.create(user, now).toString(); - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { int maxNumberOfSessions = getMaxNumberOfSessionsFor(user); if (maxNumberOfSessions > 0) @@ -269,7 +269,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa { if (sessionMonitor == null) { - synchronized (this) + synchronized (SessionManagerLock.getInstance()) { if (sessionMonitor == null) { @@ -395,7 +395,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa public boolean isSessionActive(final String sessionToken) { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { final FullSession<T> session = sessions.get(sessionToken); if (session != null) @@ -508,7 +508,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa @Override public List<T> getSessions() { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { List<T> result = new ArrayList<>(); for (FullSession<T> session : sessions.values()) @@ -522,7 +522,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa @Override public T tryGetSession(String sessionToken) { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { final FullSession<T> session = sessions.get(sessionToken); return (session == null) ? null : session.getSession(); @@ -534,7 +534,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa { checkIfNotBlank(sessionToken, "sessionToken"); - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { final FullSession<T> session = sessions.get(sessionToken); @@ -633,7 +633,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa @Override public void closeSession(final String sessionToken) throws InvalidSessionException { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { final T session = getSession(sessionToken, false); closeSession(session, SessionClosingReason.LOGOUT); @@ -650,7 +650,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa private void closeSession(final T session, SessionClosingReason reason) throws InvalidSessionException { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { session.cleanup(); String sessionToken = session.getSessionToken(); diff --git a/lib-authentication/source/java/ch/systemsx/cisd/authentication/SessionManagerLock.java b/lib-authentication/source/java/ch/systemsx/cisd/authentication/SessionManagerLock.java new file mode 100644 index 00000000000..2dc0c3f9c8d --- /dev/null +++ b/lib-authentication/source/java/ch/systemsx/cisd/authentication/SessionManagerLock.java @@ -0,0 +1,13 @@ +package ch.systemsx.cisd.authentication; + +public class SessionManagerLock +{ + + private static final SessionManagerLock instance = new SessionManagerLock(); + + private SessionManagerLock(){} + + public static SessionManagerLock getInstance(){ + return instance; + } +} diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java index 1f7bb137f66..bfc7300d1d8 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java @@ -25,6 +25,7 @@ import ch.systemsx.cisd.authentication.DefaultSessionManager; import ch.systemsx.cisd.authentication.IAuthenticationService; import ch.systemsx.cisd.authentication.ILogMessagePrefixGenerator; import ch.systemsx.cisd.authentication.ISessionFactory; +import ch.systemsx.cisd.authentication.SessionManagerLock; import ch.systemsx.cisd.common.server.IRemoteHostProvider; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager; @@ -111,7 +112,7 @@ public class OpenBisSessionManager extends DefaultSessionManager<Session> implem @Override public void updateAllSessions() { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { List<Session> list = sessions.values().stream().map(FullSession::getSession).collect(Collectors.toList()); updateSessions(daoFactory, list); diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/pat/PersonalAccessTokenOpenBisSessionManagerDecorator.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/pat/PersonalAccessTokenOpenBisSessionManagerDecorator.java index 1388917db21..9a76f24c8e8 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/pat/PersonalAccessTokenOpenBisSessionManagerDecorator.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/pat/PersonalAccessTokenOpenBisSessionManagerDecorator.java @@ -33,6 +33,7 @@ import ch.systemsx.cisd.authentication.IPrincipalProvider; import ch.systemsx.cisd.authentication.ISessionActionListener; import ch.systemsx.cisd.authentication.ISessionFactory; import ch.systemsx.cisd.authentication.Principal; +import ch.systemsx.cisd.authentication.SessionManagerLock; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; @@ -111,7 +112,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB { sessionManager.updateAllSessions(); - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { OpenBisSessionManager.updateSessions(daoFactory, sessions.values()); } @@ -152,7 +153,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB return; } - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { Session session = sessions.get(sessionToken); @@ -181,7 +182,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB return; } - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { Session session = sessions.get(sessionToken); @@ -216,7 +217,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB return sessionManager.getSession(sessionToken); } else { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { Session session = getOrCreateSessionForPATSession(patSession); @@ -253,7 +254,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB return sessionManager.tryGetSession(sessionToken); } else { - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { return getOrCreateSessionForPATSession(patSession); } @@ -275,7 +276,7 @@ public class PersonalAccessTokenOpenBisSessionManagerDecorator implements IOpenB allSessions.put(session.getSessionToken(), session); } - synchronized (sessions) + synchronized (SessionManagerLock.getInstance()) { allSessions.putAll(sessions); -- GitLab