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 d0c3b36f..6d8b473e 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 @@ -17,38 +17,162 @@ package io.openvidu.server.core; +import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import com.google.gson.JsonArray; 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.Recording; +import io.openvidu.java.client.RecordingLayout; import io.openvidu.java.client.SessionProperties; +import io.openvidu.server.cdr.CallDetailRecord; +import io.openvidu.server.config.OpenviduConfig; +import io.openvidu.server.kurento.core.KurentoParticipant; +import io.openvidu.server.recording.service.RecordingManager; -public interface Session { +public class Session implements SessionInterface { - String getSessionId(); + protected OpenviduConfig openviduConfig; + protected RecordingManager recordingManager; + protected CallDetailRecord CDR; - SessionProperties getSessionProperties(); + protected final ConcurrentMap participants = new ConcurrentHashMap<>(); + protected String sessionId; + protected SessionProperties sessionProperties; + protected Long startTime; - void join(Participant participant); + protected volatile boolean closed = false; + protected AtomicInteger activePublishers = new AtomicInteger(0); - void leave(String participantPrivateId, String reason); + public Session(Session previousSession) { + this.sessionId = previousSession.getSessionId(); + this.startTime = previousSession.getStartTime(); + this.sessionProperties = previousSession.getSessionProperties(); + this.CDR = previousSession.CDR; + this.openviduConfig = previousSession.openviduConfig; + this.recordingManager = previousSession.recordingManager; + } - boolean close(String reason); + public Session(String sessionId, SessionProperties sessionProperties, CallDetailRecord CDR, + OpenviduConfig openviduConfig, RecordingManager recordingManager) { + this.sessionId = sessionId; + this.startTime = System.currentTimeMillis(); + this.sessionProperties = sessionProperties; + this.CDR = CDR; + this.openviduConfig = openviduConfig; + this.recordingManager = recordingManager; + } - boolean isClosed(); + public String getSessionId() { + return this.sessionId; + } - Set getParticipants(); + public SessionProperties getSessionProperties() { + return this.sessionProperties; + } - Participant getParticipantByPrivateId(String participantPrivateId); + public Long getStartTime() { + return this.startTime; + } - Participant getParticipantByPublicId(String participantPublicId); + public Set getParticipants() { + checkClosed(); + return new HashSet(this.participants.values()); + } - int getActivePublishers(); + public Participant getParticipantByPrivateId(String participantPrivateId) { + checkClosed(); + return participants.get(participantPrivateId); + } - JsonObject toJson(); + public Participant getParticipantByPublicId(String participantPublicId) { + checkClosed(); + for (Participant p : participants.values()) { + if (p.getParticipantPublicId().equals(participantPublicId)) { + return p; + } + } + return null; + } - JsonObject withStatsToJson(); + public int getActivePublishers() { + return activePublishers.get(); + } - Long getStartTime(); + public void registerPublisher() { + this.activePublishers.incrementAndGet(); + } + + public void deregisterPublisher() { + this.activePublishers.decrementAndGet(); + } + + public boolean isClosed() { + return closed; + } + + protected void checkClosed() { + if (isClosed()) { + throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "The session '" + sessionId + "' is closed"); + } + } + + public JsonObject toJson() { + return this.sharedJson(KurentoParticipant::toJson); + } + + public JsonObject withStatsToJson() { + return this.sharedJson(KurentoParticipant::withStatsToJson); + } + + private JsonObject sharedJson(Function toJsonFunction) { + JsonObject json = new JsonObject(); + json.addProperty("sessionId", this.sessionId); + json.addProperty("createdAt", this.startTime); + json.addProperty("mediaMode", this.sessionProperties.mediaMode().name()); + json.addProperty("recordingMode", this.sessionProperties.recordingMode().name()); + json.addProperty("defaultOutputMode", this.sessionProperties.defaultOutputMode().name()); + if (Recording.OutputMode.COMPOSED.equals(this.sessionProperties.defaultOutputMode())) { + json.addProperty("defaultRecordingLayout", this.sessionProperties.defaultRecordingLayout().name()); + if (RecordingLayout.CUSTOM.equals(this.sessionProperties.defaultRecordingLayout())) { + json.addProperty("defaultCustomLayout", this.sessionProperties.defaultCustomLayout()); + } + } + if (this.sessionProperties.customSessionId() != null) { + json.addProperty("customSessionId", this.sessionProperties.customSessionId()); + } + JsonObject connections = new JsonObject(); + JsonArray participants = new JsonArray(); + this.participants.values().forEach(p -> { + if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(p.getParticipantPublicId())) { + participants.add(toJsonFunction.apply((KurentoParticipant) p)); + } + }); + connections.addProperty("numberOfElements", participants.size()); + connections.add("content", participants); + json.add("connections", connections); + return json; + } + + @Override + public void join(Participant participant) { + } + + @Override + public void leave(String participantPrivateId, String reason) { + } + + @Override + public boolean close(String reason) { + return false; + } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionInterface.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionInterface.java new file mode 100644 index 00000000..94bf694d --- /dev/null +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionInterface.java @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2017-2019 OpenVidu (https://openvidu.io/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.openvidu.server.core; + +import java.util.Set; + +import com.google.gson.JsonObject; + +import io.openvidu.java.client.SessionProperties; + +public interface SessionInterface { + + String getSessionId(); + + SessionProperties getSessionProperties(); + + void join(Participant participant); + + void leave(String participantPrivateId, String reason); + + boolean close(String reason); + + boolean isClosed(); + + Set getParticipants(); + + Participant getParticipantByPrivateId(String participantPrivateId); + + Participant getParticipantByPublicId(String participantPublicId); + + int getActivePublishers(); + + JsonObject toJson(); + + JsonObject withStatsToJson(); + + Long getStartTime(); + +} 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 7f45b307..01a6ff20 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 @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; import javax.annotation.PreDestroy; @@ -69,9 +70,9 @@ public abstract class SessionManager { public FormatChecker formatChecker = new FormatChecker(); protected ConcurrentMap sessions = new ConcurrentHashMap<>(); - protected ConcurrentMap sessionProperties = new ConcurrentHashMap<>(); - protected ConcurrentMap sessionCreationTime = new ConcurrentHashMap<>(); + protected ConcurrentMap sessionsNotActive = new ConcurrentHashMap<>(); protected ConcurrentMap> sessionidParticipantpublicidParticipant = new ConcurrentHashMap<>(); + protected ConcurrentMap insecureUsers = new ConcurrentHashMap<>(); public ConcurrentMap> sessionidTokenTokenobj = new ConcurrentHashMap<>(); @@ -137,17 +138,21 @@ public abstract class SessionManager { * * @return set of the session's identifiers */ - public Set getSessions() { - return new HashSet(sessions.keySet()); + public Collection getSessions() { + return sessions.values(); } - /** - * Returns all currently active (opened) sessions. - * - * @return set of the session's identifiers - */ - public Collection getSessionObjects() { - return sessions.values(); + public Session getSessionNotActive(String sessionId) { + return this.sessionsNotActive.get(sessionId); + } + + public Collection getSessionsWithNotActive() { + Collection allSessions = new HashSet<>(); + allSessions.addAll(this.sessionsNotActive.values().stream() + .filter(sessionNotActive -> !sessions.containsKey(sessionNotActive.getSessionId())) + .collect(Collectors.toSet())); + allSessions.addAll(this.getSessions()); + return allSessions; } /** @@ -212,11 +217,12 @@ public abstract class SessionManager { return null; } - public void storeSessionId(String sessionId, Long creationTime, SessionProperties sessionProperties) { + public Session storeSessionNotActive(String sessionId, SessionProperties sessionProperties) { + Session sessionNotActive = new Session(sessionId, sessionProperties, CDR, openviduConfig, recordingManager); + this.sessionsNotActive.put(sessionId, sessionNotActive); this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>()); - this.sessionProperties.putIfAbsent(sessionId, sessionProperties); - this.sessionCreationTime.putIfAbsent(sessionId, creationTime); showTokens(); + return sessionNotActive; } public String newToken(String sessionId, ParticipantRole role, String serverMetadata, @@ -254,7 +260,6 @@ public abstract class SessionManager { log.error("sessionId [" + sessionId + "] was not found"); throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "sessionId [" + sessionId + "] not found"); } - } public boolean isTokenValidInSession(String token, String sessionId, String participanPrivatetId) { @@ -266,7 +271,6 @@ public abstract class SessionManager { } } else { this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>()); - this.sessionCreationTime.putIfAbsent(sessionId, System.currentTimeMillis()); this.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>()); this.sessionidTokenTokenobj.get(sessionId).putIfAbsent(token, new Token(token, ParticipantRole.PUBLISHER, "", @@ -278,15 +282,6 @@ public abstract class SessionManager { } } - 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"); - } - } - public boolean isPublisherInSession(String sessionId, Participant participant) { if (!this.isInsecureParticipant(participant.getParticipantPrivateId())) { if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) { @@ -371,14 +366,6 @@ public abstract class SessionManager { log.info(": {}", this.sessionidTokenTokenobj.toString()); } - public void showInsecureParticipants() { - log.info(": {}", this.insecureUsers.toString()); - } - - public void showAllParticipants() { - log.info(": {}", this.sessionidParticipantpublicidParticipant.toString()); - } - public String generateRandomChain() { return RandomStringUtils.randomAlphanumeric(16).toLowerCase(); } @@ -454,8 +441,7 @@ public abstract class SessionManager { } sessions.remove(session.getSessionId()); - sessionProperties.remove(session.getSessionId()); - sessionCreationTime.remove(session.getSessionId()); + sessionsNotActive.remove(session.getSessionId()); sessionidParticipantpublicidParticipant.remove(session.getSessionId()); sessionidTokenTokenobj.remove(session.getSessionId()); diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java index ff30993a..591e7e50 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java @@ -17,14 +17,9 @@ package io.openvidu.server.kurento.core; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import org.kurento.client.Continuation; import org.kurento.client.ErrorEvent; @@ -35,83 +30,44 @@ import org.kurento.client.MediaPipeline; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.JsonArray; -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.Recording; -import io.openvidu.java.client.RecordingLayout; -import io.openvidu.java.client.SessionProperties; -import io.openvidu.server.cdr.CallDetailRecord; -import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.core.Participant; import io.openvidu.server.core.Session; -import io.openvidu.server.recording.service.RecordingManager; /** * @author Pablo Fuente (pablofuenteperez@gmail.com) */ -public class KurentoSession implements Session { +public class KurentoSession extends Session { private final static Logger log = LoggerFactory.getLogger(Session.class); public static final int ASYNC_LATCH_TIMEOUT = 30; - private OpenviduConfig openviduConfig; - private RecordingManager recordingManager; - - private final ConcurrentMap participants = new ConcurrentHashMap<>(); - private String sessionId; - private SessionProperties sessionProperties; - private Long startTime; - private MediaPipeline pipeline; private CountDownLatch pipelineLatch = new CountDownLatch(1); private KurentoClient kurentoClient; private KurentoSessionEventsHandler kurentoSessionHandler; - private volatile boolean closed = false; - private final ConcurrentHashMap filterStates = new ConcurrentHashMap<>(); - private AtomicInteger activePublishers = new AtomicInteger(0); private Object pipelineCreateLock = new Object(); private Object pipelineReleaseLock = new Object(); private volatile boolean pipelineReleased = false; private boolean destroyKurentoClient; - private CallDetailRecord CDR; - public final ConcurrentHashMap publishedStreamIds = new ConcurrentHashMap<>(); - public KurentoSession(String sessionId, Long startTime, SessionProperties sessionProperties, - KurentoClient kurentoClient, KurentoSessionEventsHandler kurentoSessionHandler, - boolean destroyKurentoClient, CallDetailRecord CDR, OpenviduConfig openviduConfig, - RecordingManager recordingManager) { - this.sessionId = sessionId; - this.sessionProperties = sessionProperties; + public KurentoSession(Session sessionNotActive, KurentoClient kurentoClient, + KurentoSessionEventsHandler kurentoSessionHandler, boolean destroyKurentoClient) { + super(sessionNotActive); this.kurentoClient = kurentoClient; this.destroyKurentoClient = destroyKurentoClient; this.kurentoSessionHandler = kurentoSessionHandler; - this.CDR = CDR; - this.openviduConfig = openviduConfig; - this.recordingManager = recordingManager; - this.startTime = startTime; log.debug("New SESSION instance with id '{}'", sessionId); } - @Override - public String getSessionId() { - return this.sessionId; - } - - @Override - public SessionProperties getSessionProperties() { - return this.sessionProperties; - } - @Override public void join(Participant participant) { checkClosed(); @@ -137,11 +93,11 @@ public class KurentoSession implements Session { registerPublisher(); // pre-load endpoints to recv video from the new publisher - for (KurentoParticipant p : participants.values()) { + for (Participant p : participants.values()) { if (participant.equals(p)) { continue; } - p.getNewOrExistingSubscriber(participant.getParticipantPublicId()); + ((KurentoParticipant) p).getNewOrExistingSubscriber(participant.getParticipantPublicId()); } log.debug("SESSION {}: Virtually subscribed other participants {} to new publisher {}", sessionId, @@ -152,11 +108,11 @@ public class KurentoSession implements Session { deregisterPublisher(); // cancel recv video from this publisher - for (KurentoParticipant subscriber : participants.values()) { + for (Participant subscriber : participants.values()) { if (participant.equals(subscriber)) { continue; } - subscriber.cancelReceivingMedia(participant.getParticipantPublicId(), reason); + ((KurentoParticipant) subscriber).cancelReceivingMedia(participant.getParticipantPublicId(), reason); } @@ -170,7 +126,7 @@ public class KurentoSession implements Session { checkClosed(); - KurentoParticipant participant = participants.get(participantPrivateId); + KurentoParticipant participant = (KurentoParticipant) participants.get(participantPrivateId); if (participant == null) { throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, "Participant with private id " + participantPrivateId + " not found in session '" + sessionId + "'"); @@ -189,36 +145,13 @@ public class KurentoSession implements Session { } } - @Override - public Set getParticipants() { - checkClosed(); - return new HashSet(this.participants.values()); - } - - @Override - public Participant getParticipantByPrivateId(String participantPrivateId) { - checkClosed(); - return participants.get(participantPrivateId); - } - - @Override - public Participant getParticipantByPublicId(String participantPublicId) { - checkClosed(); - for (Participant p : participants.values()) { - if (p.getParticipantPublicId().equals(participantPublicId)) { - return p; - } - } - return null; - } - @Override public boolean close(String reason) { if (!closed) { - for (KurentoParticipant participant : participants.values()) { - participant.releaseAllFilters(); - participant.close(reason); + for (Participant participant : participants.values()) { + ((KurentoParticipant) participant).releaseAllFilters(); + ((KurentoParticipant) participant).close(reason); } participants.clear(); @@ -247,17 +180,6 @@ public class KurentoSession implements Session { this.kurentoSessionHandler.onMediaElementError(sessionId, participantId, description); } - @Override - public boolean isClosed() { - return closed; - } - - private void checkClosed() { - if (isClosed()) { - throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "The session '" + sessionId + "' is closed"); - } - } - private void removeParticipant(Participant participant, String reason) { checkClosed(); @@ -266,24 +188,11 @@ public class KurentoSession implements Session { log.debug("SESSION {}: Cancel receiving media from participant '{}' for other participant", this.sessionId, participant.getParticipantPublicId()); - for (KurentoParticipant other : participants.values()) { - other.cancelReceivingMedia(participant.getParticipantPublicId(), reason); + for (Participant other : participants.values()) { + ((KurentoParticipant) other).cancelReceivingMedia(participant.getParticipantPublicId(), reason); } } - @Override - public int getActivePublishers() { - return activePublishers.get(); - } - - public void registerPublisher() { - this.activePublishers.incrementAndGet(); - } - - public void deregisterPublisher() { - this.activePublishers.decrementAndGet(); - } - public MediaPipeline getPipeline() { try { pipelineLatch.await(KurentoSession.ASYNC_LATCH_TIMEOUT, TimeUnit.SECONDS); @@ -361,63 +270,8 @@ public class KurentoSession implements Session { } } - public synchronized void updateFilter(String filterId) { - String state = filterStates.get(filterId); - String newState = kurentoSessionHandler.getNextFilterState(filterId, state); - - filterStates.put(filterId, newState); - - for (Participant participant : participants.values()) { - kurentoSessionHandler.updateFilter(this.sessionId, participant, filterId, newState); - } - } - - @Override - public JsonObject toJson() { - return this.sharedJson(KurentoParticipant::toJson); - } - - @Override - public JsonObject withStatsToJson() { - return this.sharedJson(KurentoParticipant::withStatsToJson); - } - - private JsonObject sharedJson(Function toJsonFunction) { - JsonObject json = new JsonObject(); - json.addProperty("sessionId", this.sessionId); - json.addProperty("createdAt", this.startTime); - json.addProperty("mediaMode", this.sessionProperties.mediaMode().name()); - json.addProperty("recordingMode", this.sessionProperties.recordingMode().name()); - json.addProperty("defaultOutputMode", this.sessionProperties.defaultOutputMode().name()); - if (Recording.OutputMode.COMPOSED.equals(this.sessionProperties.defaultOutputMode())) { - json.addProperty("defaultRecordingLayout", this.sessionProperties.defaultRecordingLayout().name()); - if (RecordingLayout.CUSTOM.equals(this.sessionProperties.defaultRecordingLayout())) { - json.addProperty("defaultCustomLayout", this.sessionProperties.defaultCustomLayout()); - } - } - if (this.sessionProperties.customSessionId() != null) { - json.addProperty("customSessionId", this.sessionProperties.customSessionId()); - } - JsonObject connections = new JsonObject(); - JsonArray participants = new JsonArray(); - this.participants.values().forEach(p -> { - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(p.getParticipantPublicId())) { - participants.add(toJsonFunction.apply(p)); - } - }); - connections.addProperty("numberOfElements", participants.size()); - connections.add("content", participants); - json.add("connections", connections); - return json; - } - public String getParticipantPrivateIdFromStreamId(String streamId) { return this.publishedStreamIds.get(streamId); } - @Override - public Long getStartTime() { - return this.startTime; - } - } 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 83663c8c..2fa20b70 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 @@ -80,13 +80,19 @@ public class KurentoSessionManager extends SessionManager { KurentoSession session = (KurentoSession) sessions.get(sessionId); if (session == null && kcSessionInfo != null) { - SessionProperties properties = sessionProperties.get(sessionId); - if (properties == null && this.isInsecureParticipant(participant.getParticipantPrivateId())) { - properties = new SessionProperties.Builder().mediaMode(MediaMode.ROUTED) - .recordingMode(RecordingMode.ALWAYS).defaultRecordingLayout(RecordingLayout.BEST_FIT) - .build(); + // First user connecting to the session + Session sessionNotActive = sessionsNotActive.remove(sessionId); + + if (sessionNotActive == null && this.isInsecureParticipant(participant.getParticipantPrivateId())) { + // Insecure user directly call joinRoom RPC method, without REST API use + sessionNotActive = new Session(sessionId, + new SessionProperties.Builder().mediaMode(MediaMode.ROUTED) + .recordingMode(RecordingMode.ALWAYS) + .defaultRecordingLayout(RecordingLayout.BEST_FIT).build(), + CDR, openviduConfig, recordingManager); } - createSession(kcSessionInfo, properties); + + createSession(sessionNotActive, kcSessionInfo); } session = (KurentoSession) sessions.get(sessionId); if (session == null) { @@ -489,7 +495,7 @@ public class KurentoSessionManager extends SessionManager { * {@link KurentoClient} that will be used by the room * @throws OpenViduException in case of error while creating the session */ - public void createSession(KurentoClientSessionInfo kcSessionInfo, SessionProperties sessionProperties) + public void createSession(Session sessionNotActive, KurentoClientSessionInfo kcSessionInfo) throws OpenViduException { String sessionId = kcSessionInfo.getRoomName(); KurentoSession session = (KurentoSession) sessions.get(sessionId); @@ -498,9 +504,8 @@ public class KurentoSessionManager extends SessionManager { "Session '" + sessionId + "' already exists"); } this.kurentoClient = kcProvider.getKurentoClient(kcSessionInfo); - session = new KurentoSession(sessionId, this.sessionCreationTime.get(sessionId), sessionProperties, - kurentoClient, kurentoSessionEventsHandler, kcProvider.destroyWhenUnused(), this.CDR, - this.openviduConfig, this.recordingManager); + session = new KurentoSession(sessionNotActive, kurentoClient, kurentoSessionEventsHandler, + kcProvider.destroyWhenUnused()); KurentoSession oldSession = (KurentoSession) sessions.putIfAbsent(sessionId, session); if (oldSession != null) { 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 813431bc..e0cf1f38 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 @@ -158,11 +158,10 @@ public class SessionRestController { sessionManager.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>()); } - Long creationTime = System.currentTimeMillis(); - sessionManager.storeSessionId(sessionId, creationTime, sessionProperties); + Session sessionNotActive = sessionManager.storeSessionNotActive(sessionId, sessionProperties); JsonObject responseJson = new JsonObject(); - responseJson.addProperty("id", sessionId); - responseJson.addProperty("createdAt", creationTime); + responseJson.addProperty("id", sessionNotActive.getSessionId()); + responseJson.addProperty("createdAt", sessionNotActive.getStartTime()); return new ResponseEntity<>(responseJson.toString(), getResponseHeaders(), HttpStatus.OK); } @@ -179,7 +178,14 @@ public class SessionRestController { response.addProperty("recording", this.recordingManager.sessionIsBeingRecorded(sessionId)); return new ResponseEntity<>(response.toString(), getResponseHeaders(), HttpStatus.OK); } else { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + Session sessionNotActive = this.sessionManager.getSessionNotActive(sessionId); + if (sessionNotActive != null) { + JsonObject response = (webRtcStats == true) ? sessionNotActive.withStatsToJson() + : sessionNotActive.toJson(); + return new ResponseEntity<>(response.toString(), getResponseHeaders(), HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } } } @@ -189,7 +195,7 @@ public class SessionRestController { log.info("REST API: GET /api/sessions"); - Collection sessions = this.sessionManager.getSessionObjects(); + Collection sessions = this.sessionManager.getSessionsWithNotActive(); JsonObject json = new JsonObject(); JsonArray jsonArray = new JsonArray(); sessions.forEach(s -> { @@ -212,7 +218,13 @@ public class SessionRestController { this.sessionManager.closeSession(sessionId, "sessionClosedByServer"); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + Session sessionNotActive = this.sessionManager.getSessionNotActive(sessionId); + if (sessionNotActive != null) { + this.sessionManager.closeSessionAndEmptyCollections(sessionNotActive, "sessionClosedByServer"); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } } } @@ -232,6 +244,9 @@ public class SessionRestController { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } else { + if (this.sessionManager.getSessionNotActive(sessionId) != null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -250,6 +265,9 @@ public class SessionRestController { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } else { + if (this.sessionManager.getSessionNotActive(sessionId) != null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -390,6 +408,10 @@ public class SessionRestController { Session session = sessionManager.getSession(sessionId); if (session == null) { + if (sessionManager.getSessionNotActive(sessionId) != null) { + // Session is not active + return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); + } // Session does not exist return new ResponseEntity<>(HttpStatus.NOT_FOUND); }