diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Session.java b/openvidu-server/src/main/java/io/openvidu/server/core/Session.java index 7edf339c..ddcd6759 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/Session.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/Session.java @@ -18,6 +18,8 @@ package io.openvidu.server.core; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -157,13 +159,25 @@ public class Session implements SessionInterface { this.tokens.put(token.getToken(), token); } + public boolean deleteTokenFromConnectionId(String connectionId) { + boolean deleted = false; + Iterator> iterator = this.tokens.entrySet().iterator(); + while (iterator.hasNext() && !deleted) { + Entry entry = iterator.next(); + if (connectionId.equals(entry.getValue().getConnetionId())) { + iterator.remove(); + deleted = true; + } + } + return deleted; + } + public boolean isTokenValid(String token) { return this.tokens.containsKey(token); } public Token consumeToken(String token) { Token tokenObj = this.tokens.remove(token); - showTokens("Token consumed"); return tokenObj; } 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 91dd8fd6..1b1bc4d6 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 @@ -32,7 +32,6 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import org.apache.commons.lang3.RandomStringUtils; import org.kurento.jsonrpc.message.Request; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -295,7 +294,7 @@ public abstract class SessionManager { return sessionNotActive; } - public String newToken(Session session, OpenViduRole role, String serverMetadata, + public Token newToken(Session session, OpenViduRole role, String serverMetadata, KurentoTokenOptions kurentoTokenOptions) throws Exception { if (!formatChecker.isServerMetadataFormatCorrect(serverMetadata)) { log.error("Data invalid format"); @@ -305,7 +304,7 @@ public abstract class SessionManager { kurentoTokenOptions); session.storeToken(tokenObj); session.showTokens("Token created"); - return tokenObj.getToken(); + return tokenObj; } public Token newTokenForInsecureUser(Session session, String token, String serverMetadata) throws Exception { @@ -355,17 +354,13 @@ public abstract class SessionManager { public Participant newParticipant(String sessionId, String participantPrivatetId, Token token, String clientMetadata, GeoLocation location, String platform, String finalUserId) { + if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) { - String participantPublicId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID - + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(9); - Participant p = new Participant(finalUserId, participantPrivatetId, participantPublicId, sessionId, token, - clientMetadata, location, platform, EndpointType.WEBRTC_ENDPOINT, null); - while (this.sessionidParticipantpublicidParticipant.get(sessionId).putIfAbsent(participantPublicId, - p) != null) { - participantPublicId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID - + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(9); - p.setParticipantPublicId(participantPublicId); - } + + Participant p = new Participant(finalUserId, participantPrivatetId, token.getConnetionId(), sessionId, + token, clientMetadata, location, platform, EndpointType.WEBRTC_ENDPOINT, null); + + this.sessionidParticipantpublicidParticipant.get(sessionId).put(p.getParticipantPublicId(), p); this.sessionidFinalUsers.get(sessionId).computeIfAbsent(finalUserId, k -> { log.info("Participant {} of session {} is a final user connecting to this session for the first time", @@ -374,6 +369,7 @@ public abstract class SessionManager { }).addConnectionIfAbsent(p); return p; + } else { throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Token.java b/openvidu-server/src/main/java/io/openvidu/server/core/Token.java index feeb99af..55330548 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/Token.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/Token.java @@ -17,6 +17,8 @@ package io.openvidu.server.core; +import org.apache.commons.lang3.RandomStringUtils; + import io.openvidu.java.client.OpenViduRole; import io.openvidu.server.coturn.TurnCredentials; import io.openvidu.server.kurento.core.KurentoTokenOptions; @@ -27,12 +29,10 @@ public class Token { private OpenViduRole role; private String serverMetadata = ""; private TurnCredentials turnCredentials; - private KurentoTokenOptions kurentoTokenOptions; - public Token(String token) { - this.token = token; - } + private final String connectionId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID + + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(9); public Token(String token, OpenViduRole role, String serverMetadata, TurnCredentials turnCredentials, KurentoTokenOptions kurentoTokenOptions) { @@ -50,7 +50,7 @@ public class Token { public void setToken(String token) { this.token = token; } - + public OpenViduRole getRole() { return role; } @@ -67,6 +67,10 @@ public class Token { return kurentoTokenOptions; } + public String getConnetionId() { + return connectionId; + } + @Override public String toString() { if (this.role != null) 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 cad0d229..222729d4 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 @@ -30,7 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import io.openvidu.java.client.*; import org.apache.commons.lang3.RandomStringUtils; import org.kurento.client.GenericMediaElement; import org.kurento.client.IceCandidate; @@ -48,6 +47,12 @@ import com.google.gson.JsonObject; import io.openvidu.client.OpenViduException; import io.openvidu.client.OpenViduException.Code; import io.openvidu.client.internal.ProtocolElements; +import io.openvidu.java.client.MediaMode; +import io.openvidu.java.client.Recording; +import io.openvidu.java.client.RecordingLayout; +import io.openvidu.java.client.RecordingMode; +import io.openvidu.java.client.RecordingProperties; +import io.openvidu.java.client.SessionProperties; import io.openvidu.server.core.EndReason; import io.openvidu.server.core.FinalUser; import io.openvidu.server.core.IdentifierPrefixes; @@ -142,7 +147,8 @@ public class KurentoSessionManager extends SessionManager { // If Recording default layout is COMPOSED_QUICK_START Recording.OutputMode defaultOutputMode = kSession.getSessionProperties().defaultOutputMode(); - if (openviduConfig.isRecordingModuleEnabled() && defaultOutputMode.equals(Recording.OutputMode.COMPOSED_QUICK_START)) { + if (openviduConfig.isRecordingModuleEnabled() + && defaultOutputMode.equals(Recording.OutputMode.COMPOSED_QUICK_START)) { recordingManager.startComposedQuickStartContainer(kSession); } @@ -300,10 +306,12 @@ public class KurentoSessionManager extends SessionManager { } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) - && session.getSessionProperties().defaultOutputMode().equals(Recording.OutputMode.COMPOSED_QUICK_START) + && session.getSessionProperties().defaultOutputMode() + .equals(Recording.OutputMode.COMPOSED_QUICK_START) && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { - // If no recordings are active in COMPOSED_QUICK_START output mode, stop container + .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { + // If no recordings are active in COMPOSED_QUICK_START output mode, stop + // container recordingManager.stopComposedQuickStartContainer(session, reason); } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java index a8f8adf7..3af12ac1 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java @@ -61,6 +61,7 @@ import io.openvidu.server.core.IdentifierPrefixes; import io.openvidu.server.core.Participant; import io.openvidu.server.core.Session; import io.openvidu.server.core.SessionManager; +import io.openvidu.server.core.Token; import io.openvidu.server.kurento.core.KurentoMediaOptions; import io.openvidu.server.kurento.core.KurentoTokenOptions; import io.openvidu.server.recording.Recording; @@ -280,7 +281,12 @@ public class SessionRestController { this.sessionManager.evictParticipant(participant, null, null, EndReason.forceDisconnectByServer); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + // Try to delete unused token + if (session.deleteTokenFromConnectionId(participantPublicId)) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } } } @@ -387,14 +393,15 @@ public class SessionRestController { // While closing a session tokens can't be generated if (session.closingLock.readLock().tryLock()) { try { - String token = sessionManager.newToken(session, role, metadata, kurentoTokenOptions); + Token token = sessionManager.newToken(session, role, metadata, kurentoTokenOptions); JsonObject responseJson = new JsonObject(); - responseJson.addProperty("id", token); + responseJson.addProperty("id", token.getToken()); + responseJson.addProperty("connectionId", token.getConnetionId()); responseJson.addProperty("session", sessionId); responseJson.addProperty("role", role.toString()); responseJson.addProperty("data", metadata); - responseJson.addProperty("token", token); + responseJson.addProperty("token", token.getToken()); if (kurentoOptions != null) { JsonObject kurentoOptsResponse = new JsonObject(); diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java index bece2d68..7c66e35c 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java @@ -257,6 +257,9 @@ public class RpcHandler extends DefaultJsonRpcHandler { Token tokenObj = session.consumeToken(token); if (tokenObj != null) { + + session.showTokens("Token consumed"); + String clientMetadata = getStringParam(request, ProtocolElements.JOINROOM_METADATA_PARAM); if (sessionManager.formatChecker.isServerMetadataFormatCorrect(clientMetadata)) { diff --git a/openvidu-server/src/main/resources/application.properties b/openvidu-server/src/main/resources/application.properties index 5fdf2cc9..9f9c3c66 100644 --- a/openvidu-server/src/main/resources/application.properties +++ b/openvidu-server/src/main/resources/application.properties @@ -22,7 +22,7 @@ OPENVIDU_CDR_PATH=/opt/openvidu/cdr OPENVIDU_WEBHOOK=false OPENVIDU_WEBHOOK_ENDPOINT= OPENVIDU_WEBHOOK_HEADERS=[] -OPENVIDU_WEBHOOK_EVENTS=["sessionCreated","sessionDestroyed","participantJoined","participantLeft","webrtcConnectionCreated","webrtcConnectionDestroyed","recordingStatusChanged","filterEventDispatched","mediaNodeStatusChanged"] +OPENVIDU_WEBHOOK_EVENTS=["sessionCreated","sessionDestroyed","participantJoined","participantLeft","webrtcConnectionCreated","webrtcConnectionDestroyed","recordingStatusChanged","filterEventDispatched","mediaNodeStatusChanged","autoscaling"] OPENVIDU_RECORDING=false OPENVIDU_RECORDING_DEBUG=false