openvidu-server: CDR refactoring. Session and Participant createdAt property

pull/121/head
pabloFuente 2018-09-07 09:54:38 +02:00
parent 41a53c79f8
commit c75252508c
18 changed files with 326 additions and 213 deletions

View File

@ -19,184 +19,38 @@ package io.openvidu.server.cdr;
import com.google.gson.JsonObject;
import io.openvidu.java.client.RecordingLayout;
import io.openvidu.server.core.MediaOptions;
import io.openvidu.server.core.Participant;
import io.openvidu.server.recording.Recording;
public class CDREvent {
public class CDREvent implements Comparable<CDREvent> {
protected CDREventName eventName;
protected String sessionId;
protected Long timeStamp;
private Long startTime;
private Integer duration;
private Participant participant;
private String location;
private String platform;
private MediaOptions mediaOptions;
private String receivingFrom;
private String reason;
private CDREventName eventName;
// Recording events
private Long size;
private String id;
private String name;
private Boolean hasAudio;
private Boolean hasVideo;
private RecordingLayout recordingLayout;
public CDREvent(CDREventName eventName, CDREvent event) {
this(eventName, event.participant, event.sessionId, event.mediaOptions, event.receivingFrom, event.startTime,
event.reason);
this.duration = (int) (this.timeStamp - this.startTime / 1000);
}
public CDREvent(CDREventName eventName, CDREvent event, String reason) {
this(eventName, event.participant, event.sessionId, event.mediaOptions, event.receivingFrom, event.startTime,
reason);
this.duration = (int) (this.timeStamp - this.startTime / 1000);
}
public CDREvent(CDREventName eventName, String sessionId) {
public CDREvent(CDREventName eventName, String sessionId, Long timeStamp) {
this.eventName = eventName;
if ((sessionId.indexOf('/')) != -1) {
this.sessionId = sessionId.substring(sessionId.lastIndexOf('/') + 1, sessionId.length());
} else {
this.sessionId = sessionId;
}
this.timeStamp = System.currentTimeMillis();
this.startTime = this.timeStamp;
this.sessionId = sessionId;
this.timeStamp = timeStamp;
}
public CDREvent(CDREventName eventName, String sessionId, Recording recording, String reason) {
this.eventName = eventName;
if ((sessionId.indexOf('/')) != -1) {
this.sessionId = sessionId.substring(sessionId.lastIndexOf('/') + 1, sessionId.length());
} else {
this.sessionId = sessionId;
}
this.timeStamp = System.currentTimeMillis();
this.id = recording.getId();
this.name = recording.getName();
this.duration = (int) recording.getDuration();
this.size = recording.getSize();
this.hasAudio = recording.hasAudio();
this.hasVideo = recording.hasVideo();
this.recordingLayout = recording.getRecordingLayout();
this.reason = reason;
public String getSessionId() {
return this.sessionId;
}
public CDREvent(CDREventName eventName, Participant participant, String sessionId) {
this(eventName, sessionId);
this.participant = participant;
this.location = participant.getLocation();
this.platform = participant.getPlatform();
this.startTime = this.timeStamp;
public Long getTimestamp() {
return this.timeStamp;
}
public CDREvent(CDREventName eventName, Participant participant, String sessionId, MediaOptions mediaOptions,
String receivingFrom, Long startTime, String reason) {
this(eventName, sessionId);
this.participant = participant;
this.mediaOptions = mediaOptions;
this.receivingFrom = receivingFrom;
this.startTime = startTime;
this.reason = reason;
}
public MediaOptions getMediaOptions() {
return mediaOptions;
}
public String getParticipantPublicId() {
return this.participant.getParticipantPublicId();
}
public String getReceivingFrom() {
return this.receivingFrom;
public JsonObject toJson() {
JsonObject json = new JsonObject();
json.addProperty("sessionId", this.sessionId);
json.addProperty("timestamp", this.timeStamp);
return json;
}
@Override
public String toString() {
JsonObject json = new JsonObject();
json.addProperty("sessionId", this.sessionId);
json.addProperty("timestamp", this.timeStamp);
if (this.participant != null) {
json.addProperty("participantId", this.participant.getParticipantPublicId());
}
if (this.location != null) {
json.addProperty("location", this.location);
}
if (this.platform != null) {
json.addProperty("platform", this.platform);
}
if (this.mediaOptions != null) {
json.addProperty("connection", this.receivingFrom != null ? "INBOUND" : "OUTBOUND");
json.addProperty("audioEnabled", this.mediaOptions.hasAudio());
json.addProperty("videoEnabled", this.mediaOptions.hasVideo());
if (this.mediaOptions.hasVideo()) {
json.addProperty("videoSource", this.mediaOptions.getTypeOfVideo());
json.addProperty("videoFramerate", this.mediaOptions.getFrameRate());
}
if (this.receivingFrom != null) {
json.addProperty("receivingFrom", this.receivingFrom);
}
}
if (this.startTime != null && this.duration != null) {
json.addProperty("startTime", this.startTime);
json.addProperty("endTime", this.timeStamp);
json.addProperty("duration", (this.timeStamp - this.startTime) / 1000);
} else if (this.duration != null) {
json.addProperty("duration", duration);
}
if (this.reason != null) {
json.addProperty("reason", this.reason);
}
if (this.id != null) {
json.addProperty("id", this.id);
}
if (this.name != null) {
json.addProperty("name", this.name);
}
if (this.size != null) {
json.addProperty("size", this.size);
}
if (this.hasAudio != null) {
json.addProperty("hasAudio", this.hasAudio);
}
if (this.hasVideo != null) {
json.addProperty("hasVideo", this.hasVideo);
}
if (this.recordingLayout != null) {
json.addProperty("recordingLayout", this.recordingLayout.name());
}
JsonObject root = new JsonObject();
root.add(this.eventName.name(), json);
root.add(this.eventName.name(), this.toJson());
return root.toString();
}
@Override
public int compareTo(CDREvent other) {
if (this.participant.equals(other.participant)) {
if (this.receivingFrom != null && other.receivingFrom != null) {
if (this.receivingFrom.equals(other.receivingFrom)) {
return 0;
} else {
return 1;
}
} else {
if (this.receivingFrom == null && other.receivingFrom == null) {
return 0;
} else {
return 1;
}
}
}
return 1;
}
}

View File

@ -0,0 +1,37 @@
package io.openvidu.server.cdr;
import com.google.gson.JsonObject;
public class CDREventEnd extends CDREvent {
protected Long startTime;
protected Integer duration;
protected String reason;
public CDREventEnd(CDREventName eventName, String sessionId, Long timestamp) {
super(eventName, sessionId, timestamp);
}
public CDREventEnd(CDREventName eventName, String sessionId, Long startTime, String reason) {
super(eventName, sessionId, System.currentTimeMillis());
this.startTime = startTime;
this.duration = (int) ((this.timeStamp - this.startTime) / 1000);
this.reason = reason;
}
@Override
public JsonObject toJson() {
JsonObject json = super.toJson();
if (this.startTime != null) {
json.addProperty("startTime", this.startTime);
}
if (this.duration != null) {
json.addProperty("duration", this.duration);
}
if (this.reason != null) {
json.addProperty("reason", this.reason);
}
return json;
}
}

View File

@ -0,0 +1,32 @@
package io.openvidu.server.cdr;
import com.google.gson.JsonObject;
import io.openvidu.server.core.Participant;
public class CDREventParticipant extends CDREventEnd {
private Participant participant;
// participantJoined
public CDREventParticipant(String sessionId, Participant participant) {
super(CDREventName.participantJoined, sessionId, participant.getCreatedAt());
this.participant = participant;
}
// participantLeft
public CDREventParticipant(CDREvent event, String reason) {
super(CDREventName.participantLeft, event.getSessionId(), event.getTimestamp(), reason);
this.participant = ((CDREventParticipant) event).participant;
}
@Override
public JsonObject toJson() {
JsonObject json = super.toJson();
json.addProperty("participantId", this.participant.getParticipantPublicId());
json.addProperty("location", this.participant.getLocation());
json.addProperty("platform", this.participant.getPlatform());
return json;
}
}

View File

@ -0,0 +1,36 @@
package io.openvidu.server.cdr;
import com.google.gson.JsonObject;
import io.openvidu.server.recording.Recording;
public class CDREventRecording extends CDREventEnd {
private Recording recording;
// recordingStarted
public CDREventRecording(String sessionId, Recording recording) {
super(CDREventName.recordingStarted, sessionId, recording.getCreatedAt());
this.recording = recording;
}
// recordingStopped
public CDREventRecording(CDREvent event, String reason) {
super(CDREventName.recordingStopped, event.getSessionId(), event.getTimestamp(), reason);
this.recording = ((CDREventRecording) event).recording;
}
@Override
public JsonObject toJson() {
JsonObject json = super.toJson();
json.addProperty("id", this.recording.getId());
json.addProperty("name", this.recording.getName());
json.addProperty("recordingLayout", this.recording.getRecordingLayout().name());
json.addProperty("hasAudio", this.recording.hasAudio());
json.addProperty("hasVideo", this.recording.hasVideo());
json.addProperty("size", this.recording.getSize());
json.addProperty("duration", this.recording.getDuration());
return json;
}
}

View File

@ -0,0 +1,20 @@
package io.openvidu.server.cdr;
import io.openvidu.server.core.Session;
public class CDREventSession extends CDREventEnd {
Session session;
// sessionCreated
public CDREventSession(Session session) {
super(CDREventName.sessionCreated, session.getSessionId(), session.getStartTime());
this.session = session;
}
// sessionDestroyed
public CDREventSession(CDREvent event, String reason) {
super(CDREventName.sessionDestroyed, event.getSessionId(), event.getTimestamp(), reason);
}
}

View File

@ -0,0 +1,70 @@
package io.openvidu.server.cdr;
import com.google.gson.JsonObject;
import io.openvidu.server.core.MediaOptions;
public class CDREventWebrtcConnection extends CDREventEnd implements Comparable<CDREventWebrtcConnection> {
String participantId;
MediaOptions mediaOptions;
String receivingFrom;
// webrtcConnectionCreated
public CDREventWebrtcConnection(String sessionId, String participantId, MediaOptions mediaOptions,
String receivingFrom) {
super(CDREventName.webrtcConnectionCreated, sessionId, System.currentTimeMillis());
this.participantId = participantId;
this.mediaOptions = mediaOptions;
this.receivingFrom = receivingFrom;
}
// webrtcConnectionDestroyed
public CDREventWebrtcConnection(CDREvent event, String reason) {
super(CDREventName.webrtcConnectionDestroyed, event.getSessionId(), event.getTimestamp(), reason);
CDREventWebrtcConnection e = (CDREventWebrtcConnection) event;
this.participantId = e.participantId;
this.mediaOptions = e.mediaOptions;
this.receivingFrom = e.receivingFrom;
}
@Override
public JsonObject toJson() {
JsonObject json = super.toJson();
json.addProperty("participantId", this.participantId);
if (this.receivingFrom != null) {
json.addProperty("connection", "INBOUND");
json.addProperty("receivingFrom", this.receivingFrom);
} else {
json.addProperty("connection", "OUTBOUND");
}
if (this.mediaOptions.hasVideo()) {
json.addProperty("videoSource", this.mediaOptions.getTypeOfVideo());
json.addProperty("videoFramerate", this.mediaOptions.getFrameRate());
json.addProperty("videoDimensions", this.mediaOptions.getVideoDimensions());
}
json.addProperty("audioEnabled", this.mediaOptions.hasAudio());
json.addProperty("videoEnabled", this.mediaOptions.hasVideo());
return json;
}
public int compareTo(CDREventWebrtcConnection other) {
if (this.participantId.equals(other.participantId)) {
if (this.receivingFrom != null && other.receivingFrom != null) {
if (this.receivingFrom.equals(other.receivingFrom)) {
return 0;
} else {
return 1;
}
} else {
if (this.receivingFrom == null && other.receivingFrom == null) {
return 0;
} else {
return 1;
}
}
}
return 1;
}
}

View File

@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.core.MediaOptions;
import io.openvidu.server.core.Participant;
import io.openvidu.server.core.Session;
import io.openvidu.server.recording.Recording;
/**
@ -37,11 +38,11 @@ import io.openvidu.server.recording.Recording;
* Enabled by property 'openvidu.cdr=true'
*
* - 'sessionCreated': {sessionId, timestamp}
* - 'sessionDestroyed': {sessionId, timestamp, startTime, endTime, duration, reason}
* - 'sessionDestroyed': {sessionId, timestamp, startTime, duration, reason}
* - 'participantJoined': {sessionId, timestamp, participantId, location, platform}
* - 'participantLeft': {sessionId, timestamp, participantId, startTime, endTime, duration, reason}
* - 'participantLeft': {sessionId, timestamp, participantId, startTime, duration, reason}
* - 'webrtcConnectionCreated' {sessionId, timestamp, participantId, connection, [receivingFrom], audioEnabled, videoEnabled, [videoSource], [videoFramerate]}
* - 'webrtcConnectionDestroyed' {sessionId, timestamp, participantId, startTime, endTime, duration, connection, [receivingFrom], audioEnabled, videoEnabled, [videoSource], [videoFramerate], reason}
* - 'webrtcConnectionDestroyed' {sessionId, timestamp, participantId, startTime, duration, connection, [receivingFrom], audioEnabled, videoEnabled, [videoSource], [videoFramerate], reason}
* - 'recordingStarted' {sessionId, timestamp, id, name, hasAudio, hasVideo, recordingLayout, size}
* - 'recordingStopped' {sessionId, timestamp, id, name, hasAudio, hasVideo, recordingLayout, size}
*
@ -50,7 +51,6 @@ import io.openvidu.server.recording.Recording;
* - sessionId: string
* - timestamp: number
* - startTime: number
* - endTime: number
* - duration: number
* - participantId: string
* - connection: "INBOUND", "OUTBOUND"
@ -59,6 +59,7 @@ import io.openvidu.server.recording.Recording;
* - videoEnabled: boolean
* - videoSource: "CAMERA", "SCREEN"
* - videoFramerate: number
* - videoDimensions: string
* - id: string
* - name: string
* - hasAudio: boolean
@ -73,6 +74,7 @@ import io.openvidu.server.recording.Recording;
* - receivingFrom: only if connection = "INBOUND"
* - videoSource: only if videoEnabled = true
* - videoFramerate: only if videoEnabled = true
* - videoDimensions: only if videoEnabled = true
*
* @author Pablo Fuente (pablofuenteperez@gmail.com)
*/
@ -83,75 +85,85 @@ public class CallDetailRecord {
private CDRLogger logger;
private Map<String, CDREvent> sessions = new ConcurrentHashMap<>();
private Map<String, CDREvent> participants = new ConcurrentHashMap<>();
private Map<String, CDREvent> publications = new ConcurrentHashMap<>();
private Map<String, Set<CDREvent>> subscriptions = new ConcurrentHashMap<>();
private final List<String> lastParticipantLeftReasons = Arrays.asList(new String[] {"disconnect", "forceDisconnectByUser", "forceDisconnectByServer", "networkDisconnect"});
private Map<String, CDREventSession> sessions = new ConcurrentHashMap<>();
private Map<String, CDREventParticipant> participants = new ConcurrentHashMap<>();
private Map<String, CDREventWebrtcConnection> publications = new ConcurrentHashMap<>();
private Map<String, Set<CDREventWebrtcConnection>> subscriptions = new ConcurrentHashMap<>();
private Map<String, CDREventRecording> recordings = new ConcurrentHashMap<>();
private final List<String> lastParticipantLeftReasons = Arrays.asList(
new String[] { "disconnect", "forceDisconnectByUser", "forceDisconnectByServer", "networkDisconnect" });
public CallDetailRecord(CDRLogger logger) {
this.logger = logger;
}
public void recordSessionCreated(String sessionId) {
CDREvent e = new CDREvent(CDREventName.sessionCreated, sessionId);
this.sessions.put(sessionId, e);
if (openviduConfig.isCdrEnabled()) this.logger.log(e);
public void recordSessionCreated(Session session) {
CDREventSession e = new CDREventSession(session);
this.sessions.put(session.getSessionId(), e);
if (openviduConfig.isCdrEnabled())
this.logger.log(e);
}
public void recordSessionDestroyed(String sessionId, String reason) {
CDREvent e = this.sessions.remove(sessionId);
if (openviduConfig.isCdrEnabled()) this.logger.log(new CDREvent(CDREventName.sessionDestroyed, e, this.finalReason(reason)));
if (openviduConfig.isCdrEnabled())
this.logger.log(new CDREventSession(e, this.finalReason(reason)));
}
public void recordParticipantJoined(Participant participant, String sessionId) {
CDREvent e = new CDREvent(CDREventName.participantJoined, participant, sessionId);
CDREventParticipant e = new CDREventParticipant(sessionId, participant);
this.participants.put(participant.getParticipantPublicId(), e);
if (openviduConfig.isCdrEnabled()) this.logger.log(e);
if (openviduConfig.isCdrEnabled())
this.logger.log(e);
}
public void recordParticipantLeft(Participant participant, String sessionId, String reason) {
CDREvent e = this.participants.remove(participant.getParticipantPublicId());
if (openviduConfig.isCdrEnabled()) this.logger.log(new CDREvent(CDREventName.participantLeft, e, reason));
if (openviduConfig.isCdrEnabled())
this.logger.log(new CDREventParticipant(e, reason));
}
public void recordNewPublisher(Participant participant, String sessionId, MediaOptions mediaOptions) {
CDREvent publisher = new CDREvent(CDREventName.webrtcConnectionCreated, participant, sessionId, mediaOptions,
null, System.currentTimeMillis(), null);
CDREventWebrtcConnection publisher = new CDREventWebrtcConnection(sessionId,
participant.getParticipantPublicId(), mediaOptions, null);
this.publications.put(participant.getParticipantPublicId(), publisher);
if (openviduConfig.isCdrEnabled()) this.logger.log(publisher);
if (openviduConfig.isCdrEnabled())
this.logger.log(publisher);
}
public boolean stopPublisher(String participantPublicId, String reason) {
CDREvent publisher = this.publications.remove(participantPublicId);
CDREventWebrtcConnection publisher = this.publications.remove(participantPublicId);
if (publisher != null) {
publisher = new CDREvent(CDREventName.webrtcConnectionDestroyed, publisher, reason);
if (openviduConfig.isCdrEnabled()) this.logger.log(publisher);
publisher = new CDREventWebrtcConnection(publisher, reason);
if (openviduConfig.isCdrEnabled())
this.logger.log(publisher);
return true;
}
return false;
}
public void recordNewSubscriber(Participant participant, String sessionId, String senderPublicId) {
CDREvent publisher = this.publications.get(senderPublicId);
CDREvent subscriber = new CDREvent(CDREventName.webrtcConnectionCreated, participant, sessionId,
publisher.getMediaOptions(), publisher.getParticipantPublicId(), System.currentTimeMillis(), null);
CDREventWebrtcConnection publisher = this.publications.get(senderPublicId);
CDREventWebrtcConnection subscriber = new CDREventWebrtcConnection(sessionId,
participant.getParticipantPublicId(), publisher.mediaOptions, senderPublicId);
this.subscriptions.putIfAbsent(participant.getParticipantPublicId(), new ConcurrentSkipListSet<>());
this.subscriptions.get(participant.getParticipantPublicId()).add(subscriber);
if (openviduConfig.isCdrEnabled()) this.logger.log(subscriber);
if (openviduConfig.isCdrEnabled())
this.logger.log(subscriber);
}
public boolean stopSubscriber(String participantPublicId, String senderPublicId, String reason) {
Set<CDREvent> participantSubscriptions = this.subscriptions.get(participantPublicId);
Set<CDREventWebrtcConnection> participantSubscriptions = this.subscriptions.get(participantPublicId);
if (participantSubscriptions != null) {
CDREvent subscription;
for (Iterator<CDREvent> it = participantSubscriptions.iterator(); it.hasNext();) {
CDREventWebrtcConnection subscription;
for (Iterator<CDREventWebrtcConnection> it = participantSubscriptions.iterator(); it.hasNext();) {
subscription = it.next();
if (subscription.getReceivingFrom().equals(senderPublicId)) {
if (senderPublicId.equals(subscription.receivingFrom)) {
it.remove();
subscription = new CDREvent(CDREventName.webrtcConnectionDestroyed, subscription, reason);
if (openviduConfig.isCdrEnabled()) this.logger.log(subscription);
subscription = new CDREventWebrtcConnection(subscription, reason);
if (openviduConfig.isCdrEnabled())
this.logger.log(subscription);
return true;
}
}
@ -160,13 +172,18 @@ public class CallDetailRecord {
}
public void recordRecordingStarted(String sessionId, Recording recording) {
if (openviduConfig.isCdrEnabled()) this.logger.log(new CDREvent(CDREventName.recordingStarted, sessionId, recording, null));
CDREventRecording recordingStartedEvent = new CDREventRecording(sessionId, recording);
this.recordings.putIfAbsent(recording.getId(), recordingStartedEvent);
if (openviduConfig.isCdrEnabled())
this.logger.log(new CDREventRecording(sessionId, recording));
}
public void recordRecordingStopped(String sessionId, Recording recording, String reason) {
if (openviduConfig.isCdrEnabled()) this.logger.log(new CDREvent(CDREventName.recordingStopped, sessionId, recording, this.finalReason(reason)));
CDREventRecording recordingStartedEvent = this.recordings.remove(recording.getId());
if (openviduConfig.isCdrEnabled())
this.logger.log(new CDREventRecording(recordingStartedEvent, this.finalReason(reason)));
}
private String finalReason(String reason) {
if (lastParticipantLeftReasons.contains(reason)) {
return "lastParticipantLeft";

View File

@ -78,6 +78,9 @@ public class OpenviduConfig {
@Value("${coturn.redis.connect-timeout}")
private String coturnRedisConnectTimeout;
@Value("${kms.stats-enabled}")
private boolean kmsStatsEnabled;
@Value("#{'${spring.profiles.active:}'.length() > 0 ? '${spring.profiles.active:}'.split(',') : \"default\"}")
private String springProfile;
@ -168,6 +171,10 @@ public class OpenviduConfig {
public String getCoturnDatabaseDbname() {
return this.coturnRedisDbname;
}
public boolean isKmsStatsEnabled() {
return this.kmsStatsEnabled;
}
public ParticipantRole[] getRolesFromRecordingNotification() {
ParticipantRole[] roles;

View File

@ -23,6 +23,7 @@ public class Participant {
private String participantPrivatetId; // ID to identify the user on server (org.kurento.jsonrpc.Session.id)
private String participantPublicId; // ID to identify the user on clients
private Long createdAt; // Timestamp when this connection was established
private String clientMetadata = ""; // Metadata provided on client side
private String serverMetadata = ""; // Metadata provided on server side
private Token token; // Token associated to this participant
@ -38,6 +39,7 @@ public class Participant {
String location, String platform) {
this.participantPrivatetId = participantPrivatetId;
this.participantPublicId = participantPublicId;
this.createdAt = System.currentTimeMillis();
this.token = token;
this.clientMetadata = clientMetadata;
if (!token.getServerMetadata().isEmpty())
@ -62,6 +64,10 @@ public class Participant {
this.participantPublicId = participantPublicId;
}
public Long getCreatedAt() {
return this.createdAt;
}
public String getClientMetadata() {
return clientMetadata;
}
@ -187,6 +193,7 @@ public class Participant {
public JsonObject toJson() {
JsonObject json = new JsonObject();
json.addProperty("connectionId", this.participantPublicId);
json.addProperty("createdAt", this.createdAt);
json.addProperty("location", this.location);
json.addProperty("platform", this.platform);
json.addProperty("token", this.token.getToken());

View File

@ -49,4 +49,6 @@ public interface Session {
JsonObject withStatsToJson();
Long getStartTime();
}

View File

@ -64,8 +64,8 @@ public class SessionEventsHandler {
ReentrantLock lock = new ReentrantLock();
public void onSessionCreated(String sessionId) {
CDR.recordSessionCreated(sessionId);
public void onSessionCreated(Session session) {
CDR.recordSessionCreated(session);
}
public void onSessionClosed(String sessionId, String reason) {
@ -501,7 +501,8 @@ public class SessionEventsHandler {
} else {
// Send response to every other user in the session different than the affected
// participant or the moderator
if (error == null && (moderator == null || !p.getParticipantPrivateId().equals(moderator.getParticipantPrivateId()))) {
if (error == null && (moderator == null
|| !p.getParticipantPrivateId().equals(moderator.getParticipantPrivateId()))) {
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
ProtocolElements.STREAMPROPERTYCHANGED_METHOD, params);
}
@ -509,8 +510,8 @@ public class SessionEventsHandler {
}
}
public void onFilterEventDispatched(String connectionId, String streamId, String filterType, String eventType, Object data,
Set<Participant> participants, Set<String> subscribedParticipants) {
public void onFilterEventDispatched(String connectionId, String streamId, String filterType, String eventType,
Object data, Set<Participant> participants, Set<String> subscribedParticipants) {
JsonObject params = new JsonObject();
params.addProperty(ProtocolElements.FILTEREVENTLISTENER_CONNECTIONID_PARAM, connectionId);
params.addProperty(ProtocolElements.FILTEREVENTLISTENER_STREAMID_PARAM, streamId);

View File

@ -67,6 +67,7 @@ public abstract class SessionManager {
protected ConcurrentMap<String, Session> sessions = new ConcurrentHashMap<>();
protected ConcurrentMap<String, SessionProperties> sessionProperties = new ConcurrentHashMap<>();
protected ConcurrentMap<String, Long> sessionCreationTime = 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<>();
@ -215,9 +216,10 @@ public abstract class SessionManager {
return null;
}
public void storeSessionId(String sessionId, SessionProperties sessionProperties) {
public void storeSessionId(String sessionId, Long creationTime, SessionProperties sessionProperties) {
this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionProperties.putIfAbsent(sessionId, sessionProperties);
this.sessionCreationTime.putIfAbsent(sessionId, creationTime);
showTokens();
}
@ -269,6 +271,7 @@ 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, "",
@ -461,6 +464,7 @@ public abstract class SessionManager {
sessions.remove(session.getSessionId());
sessionProperties.remove(session.getSessionId());
sessionCreationTime.remove(session.getSessionId());
sessionidParticipantpublicidParticipant.remove(session.getSessionId());
sessionidTokenTokenobj.remove(session.getSessionId());

View File

@ -61,6 +61,7 @@ public class KurentoSession implements Session {
private final ConcurrentMap<String, KurentoParticipant> participants = new ConcurrentHashMap<>();
private String sessionId;
private SessionProperties sessionProperties;
private Long startTime;
private MediaPipeline pipeline;
private CountDownLatch pipelineLatch = new CountDownLatch(1);
@ -82,7 +83,7 @@ public class KurentoSession implements Session {
public final ConcurrentHashMap<String, String> publishedStreamIds = new ConcurrentHashMap<>();
public KurentoSession(String sessionId, SessionProperties sessionProperties, KurentoClient kurentoClient,
public KurentoSession(String sessionId, Long startTime, SessionProperties sessionProperties, KurentoClient kurentoClient,
KurentoSessionEventsHandler kurentoSessionHandler, boolean destroyKurentoClient, CallDetailRecord CDR,
OpenviduConfig openviduConfig) {
this.sessionId = sessionId;
@ -92,6 +93,7 @@ public class KurentoSession implements Session {
this.kurentoSessionHandler = kurentoSessionHandler;
this.CDR = CDR;
this.openviduConfig = openviduConfig;
this.startTime = startTime;
log.debug("New SESSION instance with id '{}'", sessionId);
}
@ -297,6 +299,10 @@ public class KurentoSession implements Session {
@Override
public void onSuccess(MediaPipeline result) throws Exception {
pipeline = result;
if (openviduConfig.isKmsStatsEnabled()) {
pipeline.setLatencyStats(true);
log.debug("SESSION {}: WebRTC server stats enabled", sessionId);
}
pipelineLatch.countDown();
log.debug("SESSION {}: Created MediaPipeline", sessionId);
}
@ -374,6 +380,7 @@ public class KurentoSession implements Session {
private JsonObject sharedJson(Function<KurentoParticipant, JsonObject> 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("defaultRecordingLayout", this.sessionProperties.defaultRecordingLayout().name());
@ -397,4 +404,9 @@ public class KurentoSession implements Session {
return this.publishedStreamIds.get(streamId);
}
@Override
public Long getStartTime() {
return this.startTime;
}
}

View File

@ -474,8 +474,9 @@ public class KurentoSessionManager extends SessionManager {
"Session '" + sessionId + "' already exists");
}
this.kurentoClient = kcProvider.getKurentoClient(kcSessionInfo);
session = new KurentoSession(sessionId, sessionProperties, kurentoClient, kurentoSessionEventsHandler,
kcProvider.destroyWhenUnused(), this.CDR, this.openviduConfig);
session = new KurentoSession(sessionId, this.sessionCreationTime.get(sessionId), sessionProperties,
kurentoClient, kurentoSessionEventsHandler, kcProvider.destroyWhenUnused(), this.CDR,
this.openviduConfig);
KurentoSession oldSession = (KurentoSession) sessions.putIfAbsent(sessionId, session);
if (oldSession != null) {
@ -488,7 +489,7 @@ public class KurentoSessionManager extends SessionManager {
}
log.warn("No session '{}' exists yet. Created one using KurentoClient '{}'.", sessionId, kcName);
sessionEventsHandler.onSessionCreated(sessionId);
sessionEventsHandler.onSessionCreated(session);
}
@Override

View File

@ -40,6 +40,7 @@ import org.kurento.client.WebRtcEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@ -495,6 +496,9 @@ public abstract class MediaEndpoint {
json.add("receivedCandidates", new GsonBuilder().create().toJsonTree(this.receivedCandidateList));
json.addProperty("localCandidate", this.selectedLocalIceCandidate);
json.addProperty("remoteCandidate", this.selectedRemoteIceCandidate);
if (openviduConfig.isKmsStatsEnabled()) {
json.addProperty("serverStats", new Gson().toJson(this.webEndpoint.getStats()));
}
JsonArray jsonArray = new JsonArray();
for (KmsEvent event : this.kmsEvents) {

View File

@ -133,9 +133,11 @@ public class SessionRestController {
sessionManager.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>());
}
sessionManager.storeSessionId(sessionId, sessionProperties);
Long creationTime = System.currentTimeMillis();
sessionManager.storeSessionId(sessionId, creationTime, sessionProperties);
JsonObject responseJson = new JsonObject();
responseJson.addProperty("id", sessionId);
responseJson.addProperty("createdAt", creationTime);
return new ResponseEntity<>(responseJson.toString(), getResponseHeaders(), HttpStatus.OK);
}

View File

@ -6,6 +6,12 @@
"description": "KMS URL's to which OpenVidu Server will try to connect. They are tested in order until a valid one is found",
"defaultValue": "[\"ws://localhost:8888/kurento\"]"
},
{
"name": "kms.stats-enabled",
"type": "java.lang.Boolean",
"description": "Whether to activate the KMS WebRTC statistics feature or not. This may increase the processor consumption",
"defaultValue": false
},
{
"name": "openvidu.secret",
"type": "java.lang.String",
@ -69,7 +75,7 @@
"name": "openvidu.streams.video.max-recv-bandwidth",
"type": "java.lang.Integer",
"description": "Maximum video bandwidth sent from clients to OpenVidu Server, in kbps. 0 means unconstrained",
"defaultValue": 600
"defaultValue": 1000
},
{
"name": "openvidu.streams.video.min-recv-bandwidth",
@ -81,7 +87,7 @@
"name": "openvidu.streams.video.max-send-bandwidth",
"type": "java.lang.Integer",
"description": "Maximum video bandwidth sent from OpenVidu Server to clients, in kbps. 0 means unconstrained",
"defaultValue": 600
"defaultValue": 1000
},
{
"name": "openvidu.streams.video.min-send-bandwidth",

View File

@ -20,12 +20,13 @@ openvidu.recording.public-access: false
openvidu.recording.notification: publisher_moderator
openvidu.recording.custom-layout: /opt/openvidu/custom-layout
openvidu.streams.video.max-recv-bandwidth: 600
openvidu.streams.video.max-recv-bandwidth: 1000
openvidu.streams.video.min-recv-bandwidth: 300
openvidu.streams.video.max-send-bandwidth: 600
openvidu.streams.video.max-send-bandwidth: 1000
openvidu.streams.video.min-send-bandwidth: 300
kms.uris: [\"ws://localhost:8888/kurento\"]
kms.stats-enabled: false
coturn.redis.ip: 127.0.0.1
coturn.redis.dbname: 0