Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import javax.annotation.PostConstruct;
import javax.ws.rs.ProcessingException;

import io.openvidu.server.core.SessionManagerProvider;
import io.openvidu.server.core.SessionStorage;
import io.openvidu.server.core.Utils;
import org.kurento.jsonrpc.JsonUtils;
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
import org.kurento.jsonrpc.server.JsonRpcConfigurer;
Expand Down Expand Up @@ -153,6 +156,18 @@ public CoturnCredentialsService coturnCredentialsService() {
return new CoturnCredentialsServiceFactory(openviduConfig()).getCoturnCredentialsService();
}

@Bean
@ConditionalOnMissingBean
public SessionStorage sessionStorage() { return new SessionStorage(); }

@Bean
@ConditionalOnMissingBean
public Utils utils() { return new Utils(); }

@Bean
@ConditionalOnMissingBean
public SessionManagerProvider sessionManagerProvider() { return new SessionManagerProvider(); }

@Override
public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) {
registry.addHandler(rpcHandler().withPingWatchdog(true), "/openvidu");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,8 @@ public abstract class SessionManager {
@Autowired
protected CoturnCredentialsService coturnCredentialsService;

protected ConcurrentMap<String, Session> sessions = new ConcurrentHashMap<>();
protected ConcurrentMap<String, SessionProperties> sessionProperties = new ConcurrentHashMap<>();
protected ConcurrentMap<String, ConcurrentHashMap<String, Participant>> sessionidParticipantpublicidParticipant = new ConcurrentHashMap<>();
protected ConcurrentMap<String, Boolean> insecureUsers = new ConcurrentHashMap<>();
public ConcurrentMap<String, ConcurrentHashMap<String, Token>> sessionidTokenTokenobj = new ConcurrentHashMap<>();
@Autowired
protected SessionStorage sessionStorage;

private volatile boolean closed = false;

Expand Down Expand Up @@ -104,7 +101,7 @@ public abstract void evictParticipant(Participant evictedParticipant, Participan
* @return Session
*/
public Session getSession(String sessionId) {
return sessions.get(sessionId);
return this.sessionStorage.getSession(sessionId);
}

/**
Expand All @@ -113,7 +110,7 @@ public Session getSession(String sessionId) {
* @return set of the session's identifiers
*/
public Set<String> getSessions() {
return new HashSet<String>(sessions.keySet());
return this.sessionStorage.getSessions();
}

/**
Expand All @@ -122,7 +119,7 @@ public Set<String> getSessions() {
* @return set of the session's identifiers
*/
public Collection<Session> getSessionObjects() {
return sessions.values();
return this.sessionStorage.getSessionObjects();
}

/**
Expand All @@ -135,13 +132,7 @@ public Collection<Session> getSessionObjects() {
* in case the session doesn't exist
*/
public Set<Participant> getParticipants(String sessionId) throws OpenViduException {
Session session = sessions.get(sessionId);
if (session == null) {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "Session '" + sessionId + "' not found");
}
Set<Participant> participants = session.getParticipants();
participants.removeIf(p -> p.isClosed());
return participants;
return this.sessionStorage.getParticipants(sessionId);
}

/**
Expand All @@ -157,16 +148,7 @@ public Set<Participant> getParticipants(String sessionId) throws OpenViduExcepti
* belong to it
*/
public Participant getParticipant(String sessionId, String participantPrivateId) throws OpenViduException {
Session session = sessions.get(sessionId);
if (session == null) {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "Session '" + sessionId + "' not found");
}
Participant participant = session.getParticipantByPrivateId(participantPrivateId);
if (participant == null) {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE,
"Participant '" + participantPrivateId + "' not found in session '" + sessionId + "'");
}
return participant;
return this.sessionStorage.getParticipant(sessionId, participantPrivateId);
}

/**
Expand All @@ -179,124 +161,39 @@ public Participant getParticipant(String sessionId, String participantPrivateId)
* in case the participant doesn't exist
*/
public Participant getParticipant(String participantPrivateId) throws OpenViduException {
for (Session session : sessions.values()) {
if (!session.isClosed()) {
if (session.getParticipantByPrivateId(participantPrivateId) != null) {
return session.getParticipantByPrivateId(participantPrivateId);
}
}
}
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE,
"No participant with private id '" + participantPrivateId + "' was found");
return this.sessionStorage.getParticipant(participantPrivateId);
}

public MediaOptions generateMediaOptions(Request<JsonObject> request) {
return null;
}

public void storeSessionId(String sessionId, SessionProperties sessionProperties) {
this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionProperties.putIfAbsent(sessionId, sessionProperties);
showTokens();
this.sessionStorage.storeSessionId(sessionId, sessionProperties);
}

public String newToken(String sessionId, ParticipantRole role, String serverMetadata) throws OpenViduException {

ConcurrentHashMap<String, Token> map = this.sessionidTokenTokenobj.putIfAbsent(sessionId,
new ConcurrentHashMap<>());
if (map != null) {

if (!isMetadataFormatCorrect(serverMetadata)) {
log.error("Data invalid format. Max length allowed is 10000 chars");
throw new OpenViduException(Code.GENERIC_ERROR_CODE,
"Data invalid format. Max length allowed is 10000 chars");
}

String token = OpenViduServer.publicUrl;
token += "?sessionId=" + sessionId;
token += "&token=" + this.generateRandomChain();
token += "&role=" + role.name();
TurnCredentials turnCredentials = null;
if (this.coturnCredentialsService.isCoturnAvailable()) {
turnCredentials = coturnCredentialsService.createUser();
if (turnCredentials != null) {
token += "&turnUsername=" + turnCredentials.getUsername();
token += "&turnCredential=" + turnCredentials.getCredential();
}
}
Token t = new Token(token, role, serverMetadata, turnCredentials);

map.putIfAbsent(token, t);
showTokens();
return token;

} else {
this.sessionidTokenTokenobj.remove(sessionId);
log.error("sessionId [" + sessionId + "] is not valid");
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "sessionId [" + sessionId + "] not found");
}

return this.sessionStorage.newToken(sessionId, role, serverMetadata);
}

public boolean isTokenValidInSession(String token, String sessionId, String participanPrivatetId) {
if (!this.isInsecureParticipant(participanPrivatetId)) {
if (this.sessionidTokenTokenobj.get(sessionId) != null) {
return this.sessionidTokenTokenobj.get(sessionId).containsKey(token);
} else {
return false;
}
} else {
this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionidTokenTokenobj.get(sessionId).putIfAbsent(token,
new Token(token, ParticipantRole.PUBLISHER, "",
this.coturnCredentialsService.isCoturnAvailable()
? this.coturnCredentialsService.createUser()
: null));
return true;
}
return this.sessionStorage.isTokenValidInSession(token, sessionId, participanPrivatetId);
}

public boolean isParticipantInSession(String sessionId, Participant participant) {
Session session = this.sessions.get(sessionId);
if (session != null) {
return (session.getParticipantByPrivateId(participant.getParticipantPrivateId()) != null);
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "[" + sessionId + "] is not a valid sessionId");
}
return this.sessionStorage.isParticipantInSession(sessionId, participant);
}

public boolean isPublisherInSession(String sessionId, Participant participant) {
if (!this.isInsecureParticipant(participant.getParticipantPrivateId())) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
return (ParticipantRole.PUBLISHER.equals(participant.getToken().getRole())
|| ParticipantRole.MODERATOR.equals(participant.getToken().getRole()));
} else {
return false;
}
} else {
return true;
}
return this.sessionStorage.isPublisherInSession(sessionId, participant);
}

public boolean isModeratorInSession(String sessionId, Participant participant) {
if (!this.isInsecureParticipant(participant.getParticipantPrivateId())) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
return ParticipantRole.MODERATOR.equals(participant.getToken().getRole());
} else {
return false;
}
} else {
return true;
}
return this.sessionStorage.isModeratorInSession(sessionId, participant);
}

public boolean isInsecureParticipant(String participantPrivateId) {
if (this.insecureUsers.containsKey(participantPrivateId)) {
log.info("The user with private id {} is an INSECURE user", participantPrivateId);
return true;
}
return false;
return this.sessionStorage.isInsecureParticipant(participantPrivateId);
}

public boolean isMetadataFormatCorrect(String metadata) {
Expand All @@ -305,62 +202,30 @@ public boolean isMetadataFormatCorrect(String metadata) {
}

public void newInsecureParticipant(String participantPrivateId) {
this.insecureUsers.put(participantPrivateId, true);
this.sessionStorage.newInsecureParticipant(participantPrivateId);
}

public Participant newParticipant(String sessionId, String participantPrivatetId, Token token,
String clientMetadata) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
String participantPublicId = this.generateRandomChain();
Participant p = new Participant(participantPrivatetId, participantPublicId, token, clientMetadata);
while (this.sessionidParticipantpublicidParticipant.get(sessionId).putIfAbsent(participantPublicId,
p) != null) {
participantPublicId = this.generateRandomChain();
p.setParticipantPublicId(participantPublicId);
}
return p;
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId);
}
return this.sessionStorage.newParticipant(sessionId, participantPrivatetId, token, clientMetadata);
}

public Participant newRecorderParticipant(String sessionId, String participantPrivatetId, Token token,
String clientMetadata) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
Participant p = new Participant(participantPrivatetId, ProtocolElements.RECORDER_PARTICIPANT_PUBLICID,
token, clientMetadata);
this.sessionidParticipantpublicidParticipant.get(sessionId)
.put(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, p);
return p;
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId);
}
return this.sessionStorage.newRecorderParticipant(sessionId, participantPrivatetId, token, clientMetadata);
}

public Token consumeToken(String sessionId, String participantPrivateId, String token) {
if (this.sessionidTokenTokenobj.get(sessionId) != null) {
Token t = this.sessionidTokenTokenobj.get(sessionId).remove(token);
if (t != null) {
return t;
} else {
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, sessionId);
}
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId);
}
return this.sessionStorage.consumeToken(sessionId, participantPrivateId, token);
}

public void showTokens() {
log.info("<SESSIONID, TOKENS>: {}", this.sessionidTokenTokenobj.toString());
}
public void showTokens() { this.sessionStorage.showTokens(); }

public void showInsecureParticipants() {
log.info("<INSECURE_PARTICIPANTS>: {}", this.insecureUsers.toString());
this.sessionStorage.showInsecureParticipants();
}

public void showAllParticipants() {
log.info("<SESSIONID, PARTICIPANTS>: {}", this.sessionidParticipantpublicidParticipant.toString());
}
public void showAllParticipants() { this.sessionStorage.showAllParticipants(); }

public String generateRandomChain() {
return RandomStringUtils.randomAlphanumeric(16).toLowerCase();
Expand All @@ -379,7 +244,7 @@ public String generateRandomChain() {
public void close() {
closed = true;
log.info("Closing all sessions");
for (String sessionId : sessions.keySet()) {
for (String sessionId : this.sessionStorage.getSessions()) {
try {
closeSession(sessionId, "openviduServerStopped");
} catch (Exception e) {
Expand All @@ -405,7 +270,7 @@ public void close() {
* in case the session doesn't exist or has been already closed
*/
public Set<Participant> closeSession(String sessionId, String reason) {
Session session = sessions.get(sessionId);
Session session = this.sessionStorage.getSession(sessionId);
if (session == null) {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "Session '" + sessionId + "' not found");
}
Expand Down Expand Up @@ -434,11 +299,7 @@ public void closeSessionAndEmptyCollections(Session session, String reason) {
if (session.close(reason)) {
sessionEventsHandler.onSessionClosed(session.getSessionId(), reason);
}
sessions.remove(session.getSessionId());

sessionProperties.remove(session.getSessionId());
sessionidParticipantpublicidParticipant.remove(session.getSessionId());
sessionidTokenTokenobj.remove(session.getSessionId());
this.sessionStorage.emptyCollections(session);

log.warn("Session '{}' removed and closed", session.getSessionId());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.openvidu.server.core;

import io.openvidu.java.client.MediaMode;
import io.openvidu.java.client.SessionProperties;
import org.springframework.beans.factory.annotation.Autowired;

import javax.xml.ws.spi.WebServiceFeatureAnnotation;

public class SessionManagerProvider {

@Autowired
private SessionManager sessionManager;

@Autowired
private SessionStorage sessionStorage;

public SessionManager get(MediaMode mediaMode) {
if(mediaMode == MediaMode.RELAYED) {
// Implement SessionManager for MediaMode.RELAYED
}

return this.sessionManager;
}

public SessionManager get(String sessionId) {
SessionProperties sessionProperties = this.sessionStorage.getSessionProperties(sessionId);
return this.get(sessionProperties.mediaMode());
}

}
Loading