From bb9c59deed1135b82fa4ef63b2f1058b58dbcc64 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Thu, 4 Jul 2019 15:39:27 +0200 Subject: [PATCH] openvidu-server: NullPointer fix when closing not active session --- .../openvidu/server/core/SessionManager.java | 45 ++++++++++++++----- .../kurento/core/KurentoSessionManager.java | 19 ++++++-- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java index 55d591f5..fb126d7a 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java @@ -82,7 +82,7 @@ public abstract class SessionManager { public abstract void joinRoom(Participant participant, String sessionId, Integer transactionId); - public abstract void leaveRoom(Participant participant, Integer transactionId, EndReason reason, + public abstract boolean leaveRoom(Participant participant, Integer transactionId, EndReason reason, boolean closeWebSocket); public abstract void publishVideo(Participant participant, MediaOptions mediaOptions, Integer transactionId); @@ -105,8 +105,8 @@ public abstract class SessionManager { public abstract boolean unpublishStream(Session session, String streamId, Participant moderator, Integer transactionId, EndReason reason); - public abstract void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId, - EndReason reason); + public abstract boolean evictParticipant(Participant evictedParticipant, Participant moderator, + Integer transactionId, EndReason reason); public abstract void applyFilter(Session session, String streamId, String filterType, JsonObject filterOptions, Participant moderator, Integer transactionId, String reason); @@ -247,6 +247,18 @@ public abstract class SessionManager { return sessionNotActive; } + public Session storeSessionNotActive(Session sessionNotActive) { + final String sessionId = sessionNotActive.getSessionId(); + this.sessionsNotActive.put(sessionId, sessionNotActive); + this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>()); + this.sessionidFinalUsers.putIfAbsent(sessionId, new ConcurrentHashMap<>()); + if (this.openviduConfig.isRecordingModuleEnabled()) { + this.sessionidAccumulatedRecordings.putIfAbsent(sessionId, new ConcurrentLinkedQueue<>()); + } + showTokens(); + return sessionNotActive; + } + public String newToken(String sessionId, OpenViduRole role, String serverMetadata, KurentoTokenOptions kurentoTokenOptions) throws OpenViduException { @@ -440,15 +452,22 @@ public abstract class SessionManager { throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "Session '" + sessionId + "' already closed"); } Set participants = getParticipants(sessionId); + + boolean sessionClosedByLastParticipant = false; + for (Participant p : participants) { try { - this.evictParticipant(p, null, null, reason); + sessionClosedByLastParticipant = this.evictParticipant(p, null, null, reason); } catch (OpenViduException e) { log.warn("Error evicting participant '{}' from session '{}'", p.getParticipantPublicId(), sessionId, e); } } - this.closeSessionAndEmptyCollections(session, reason); + if (!sessionClosedByLastParticipant) { + // This code should never be executed, as last evicted participant must trigger + // session close + this.closeSessionAndEmptyCollections(session, reason); + } return participants; } @@ -464,14 +483,18 @@ public abstract class SessionManager { sessionEventsHandler.onSessionClosed(session.getSessionId(), reason); } - sessions.remove(session.getSessionId()); - sessionsNotActive.remove(session.getSessionId()); - sessionidParticipantpublicidParticipant.remove(session.getSessionId()); - sessionidFinalUsers.remove(session.getSessionId()); - sessionidAccumulatedRecordings.remove(session.getSessionId()); - sessionidTokenTokenobj.remove(session.getSessionId()); + this.cleanCollections(session.getSessionId()); log.info("Session '{}' removed and closed", session.getSessionId()); } + protected void cleanCollections(String sessionId) { + sessions.remove(sessionId); + sessionsNotActive.remove(sessionId); + sessionidParticipantpublicidParticipant.remove(sessionId); + sessionidFinalUsers.remove(sessionId); + sessionidAccumulatedRecordings.remove(sessionId); + sessionidTokenTokenobj.remove(sessionId); + } + } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java index 0d3051aa..b4fa4114 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java @@ -95,6 +95,9 @@ public class KurentoSessionManager extends SessionManager { try { lessLoadedKms = this.kmsManager.getLessLoadedKms(); } catch (NoSuchElementException e) { + // Restore session not active + this.cleanCollections(sessionId); + this.storeSessionNotActive(sessionNotActive); throw new OpenViduException(Code.ROOM_CANNOT_BE_CREATED_ERROR_CODE, "There is no available media server where to initialize session '" + sessionId + "'"); } @@ -122,10 +125,12 @@ public class KurentoSessionManager extends SessionManager { } @Override - public synchronized void leaveRoom(Participant participant, Integer transactionId, EndReason reason, + public synchronized boolean leaveRoom(Participant participant, Integer transactionId, EndReason reason, boolean closeWebSocket) { log.debug("Request [LEAVE_ROOM] ({})", participant.getParticipantPublicId()); + boolean sessionClosedByLastParticipant = false; + KurentoParticipant kParticipant = (KurentoParticipant) participant; KurentoSession session = kParticipant.getSession(); String sessionId = session.getSessionId(); @@ -194,6 +199,7 @@ public class KurentoSessionManager extends SessionManager { } else { log.info("No more participants in session '{}', removing it and closing it", sessionId); this.closeSessionAndEmptyCollections(session, reason); + sessionClosedByLastParticipant = true; showTokens(); } } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() @@ -212,6 +218,8 @@ public class KurentoSessionManager extends SessionManager { if (closeWebSocket) { sessionEventsHandler.closeRpcSession(participant.getParticipantPrivateId()); } + + return sessionClosedByLastParticipant; } /** @@ -522,12 +530,15 @@ public class KurentoSessionManager extends SessionManager { } @Override - public void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId, + public boolean evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId, EndReason reason) throws OpenViduException { + + boolean sessionClosedByLastParticipant = false; + if (evictedParticipant != null) { KurentoParticipant kParticipant = (KurentoParticipant) evictedParticipant; Set participants = kParticipant.getSession().getParticipants(); - this.leaveRoom(kParticipant, null, reason, false); + sessionClosedByLastParticipant = this.leaveRoom(kParticipant, null, reason, false); this.sessionEventsHandler.onForceDisconnect(moderator, evictedParticipant, participants, transactionId, null, reason); sessionEventsHandler.closeRpcSession(evictedParticipant.getParticipantPrivateId()); @@ -540,6 +551,8 @@ public class KurentoSessionManager extends SessionManager { null); } } + + return sessionClosedByLastParticipant; } @Override