openvidu-server: createdAt properties equal to CDR timestamps. KMS server events improved

pull/121/head
pabloFuente 2018-09-19 17:15:37 +02:00
parent 30874f24ce
commit e3ae7c34b2
11 changed files with 84 additions and 39 deletions

View File

@ -12,8 +12,8 @@ public class CDREventWebrtcConnection extends CDREventEnd implements Comparable<
// webrtcConnectionCreated
public CDREventWebrtcConnection(String sessionId, String participantId, MediaOptions mediaOptions,
String receivingFrom) {
super(CDREventName.webrtcConnectionCreated, sessionId, System.currentTimeMillis());
String receivingFrom, Long timestamp) {
super(CDREventName.webrtcConnectionCreated, sessionId, timestamp);
this.participantId = participantId;
this.mediaOptions = mediaOptions;
this.receivingFrom = receivingFrom;

View File

@ -124,9 +124,9 @@ public class CallDetailRecord {
this.logger.log(new CDREventParticipant(e, reason));
}
public void recordNewPublisher(Participant participant, String sessionId, MediaOptions mediaOptions) {
public void recordNewPublisher(Participant participant, String sessionId, MediaOptions mediaOptions, Long timestamp) {
CDREventWebrtcConnection publisher = new CDREventWebrtcConnection(sessionId,
participant.getParticipantPublicId(), mediaOptions, null);
participant.getParticipantPublicId(), mediaOptions, null, timestamp);
this.publications.put(participant.getParticipantPublicId(), publisher);
if (openviduConfig.isCdrEnabled())
this.logger.log(publisher);
@ -143,10 +143,10 @@ public class CallDetailRecord {
return false;
}
public void recordNewSubscriber(Participant participant, String sessionId, String senderPublicId) {
public void recordNewSubscriber(Participant participant, String sessionId, String senderPublicId, Long timestamp) {
CDREventWebrtcConnection publisher = this.publications.get(senderPublicId);
CDREventWebrtcConnection subscriber = new CDREventWebrtcConnection(sessionId,
participant.getParticipantPublicId(), publisher.mediaOptions, senderPublicId);
participant.getParticipantPublicId(), publisher.mediaOptions, senderPublicId, timestamp);
this.subscriptions.putIfAbsent(participant.getParticipantPublicId(), new ConcurrentSkipListSet<>());
this.subscriptions.get(participant.getParticipantPublicId()).add(subscriber);
if (openviduConfig.isCdrEnabled())

View File

@ -176,6 +176,10 @@ public class OpenviduConfig {
return this.kmsStatsEnabled;
}
public String getOpenViduRecordingNotification() {
return this.openviduRecordingNotification;
}
public ParticipantRole[] getRolesFromRecordingNotification() {
ParticipantRole[] roles;
switch (this.openviduRecordingNotification) {

View File

@ -36,10 +36,14 @@ public class Participant {
private final String METADATA_SEPARATOR = "%/%";
public Participant(String participantPrivatetId, String participantPublicId, Token token, String clientMetadata,
String location, String platform) {
String location, String platform, Long createdAt) {
this.participantPrivatetId = participantPrivatetId;
this.participantPublicId = participantPublicId;
if (createdAt != null) {
this.createdAt = createdAt;
} else {
this.createdAt = System.currentTimeMillis();
}
this.token = token;
this.clientMetadata = clientMetadata;
if (!token.getServerMetadata().isEmpty())

View File

@ -339,7 +339,7 @@ public abstract class SessionManager {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
String participantPublicId = this.generateRandomChain();
Participant p = new Participant(participantPrivatetId, participantPublicId, token, clientMetadata, location,
platform);
platform, null);
while (this.sessionidParticipantpublicidParticipant.get(sessionId).putIfAbsent(participantPublicId,
p) != null) {
participantPublicId = this.generateRandomChain();
@ -355,7 +355,7 @@ public abstract class SessionManager {
String clientMetadata) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
Participant p = new Participant(participantPrivatetId, ProtocolElements.RECORDER_PARTICIPANT_PUBLICID,
token, clientMetadata, null, null);
token, clientMetadata, null, null, null);
this.sessionidParticipantpublicidParticipant.get(sessionId)
.put(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, p);
return p;

View File

@ -80,7 +80,8 @@ public class KurentoParticipant extends Participant {
public KurentoParticipant(Participant participant, KurentoSession kurentoSession, MediaPipeline pipeline,
InfoHandler infoHandler, CallDetailRecord CDR, OpenviduConfig openviduConfig) {
super(participant.getParticipantPrivateId(), participant.getParticipantPublicId(), participant.getToken(),
participant.getClientMetadata(), participant.getLocation(), participant.getPlatform());
participant.getClientMetadata(), participant.getLocation(), participant.getPlatform(),
participant.getCreatedAt());
this.openviduConfig = openviduConfig;
this.session = kurentoSession;
this.pipeline = pipeline;
@ -113,8 +114,6 @@ public class KurentoParticipant extends Participant {
// Remove streamId from publisher's map
this.session.publishedStreamIds.putIfAbsent(this.getPublisherStreamId(), this.getParticipantPrivateId());
CDR.recordNewPublisher(this, this.session.getSessionId(), mediaOptions);
}
public void shapePublisherMedia(GenericMediaElement element, MediaType type) {
@ -233,6 +232,9 @@ public class KurentoParticipant extends Participant {
log.info("PARTICIPANT {}: Is now publishing video in room {}", this.getParticipantPublicId(),
this.session.getSessionId());
CDR.recordNewPublisher(this, this.session.getSessionId(), this.publisher.getMediaOptions(),
this.publisher.createdAt());
return sdpResponse;
}
@ -313,7 +315,8 @@ public class KurentoParticipant extends Participant {
senderName, this.session.getSessionId());
if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(this.getParticipantPublicId())) {
CDR.recordNewSubscriber(this, this.session.getSessionId(), sender.getParticipantPublicId());
CDR.recordNewSubscriber(this, this.session.getSessionId(), sender.getParticipantPublicId(),
subscriber.createdAt());
}
return sdpAnswer;
@ -601,14 +604,17 @@ public class KurentoParticipant extends Participant {
+ event.getState() + " | SOURCE: " + event.getSource().getName() + " | PAD: " + event.getPadName()
+ " | MEDIATYPE: " + event.getMediaType() + " | TIMESTAMP: " + System.currentTimeMillis();
endpoint.flowInMedia.put(event.getSource().getName(), event.getMediaType());
if (endpoint.getPublisher().getMediaOptions().hasAudio()
&& endpoint.getPublisher().getMediaOptions().hasVideo()
&& endpoint.flowInMedia.values().size() == 2) {
endpoint.kmsEvents.add(new KmsEvent(event));
} else if (endpoint.flowInMedia.values().size() == 1) {
endpoint.kmsEvents.add(new KmsEvent(event));
}
/*
* endpoint.flowInMedia.put(event.getSource().getName(), event.getMediaType());
* if (endpoint.getPublisher().getMediaOptions().hasAudio() &&
* endpoint.getPublisher().getMediaOptions().hasVideo() &&
* endpoint.flowInMedia.values().size() == 2) {
*/
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
/*
* } else if (endpoint.flowInMedia.values().size() == 1) {
* endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt())); }
*/
log.info(msg1);
this.infoHandler.sendInfo(msg1);
@ -619,37 +625,48 @@ public class KurentoParticipant extends Participant {
+ event.getState() + " | SOURCE: " + event.getSource().getName() + " | PAD: " + event.getPadName()
+ " | MEDIATYPE: " + event.getMediaType() + " | TIMESTAMP: " + System.currentTimeMillis();
endpoint.flowOutMedia.put(event.getSource().getName(), event.getMediaType());
if (endpoint.getPublisher().getMediaOptions().hasAudio()
&& endpoint.getPublisher().getMediaOptions().hasVideo()
&& endpoint.flowOutMedia.values().size() == 2) {
endpoint.kmsEvents.add(new KmsEvent(event));
} else if (endpoint.flowOutMedia.values().size() == 1) {
endpoint.kmsEvents.add(new KmsEvent(event));
}
/*
* endpoint.flowOutMedia.put(event.getSource().getName(), event.getMediaType());
* if (endpoint.getPublisher().getMediaOptions().hasAudio() &&
* endpoint.getPublisher().getMediaOptions().hasVideo() &&
* endpoint.flowOutMedia.values().size() == 2) {
*/
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
/*
* } else if (endpoint.flowOutMedia.values().size() == 1) {
* endpoint.kmsEvents.add(new KmsEvent(event)); }
*/
log.info(msg1);
this.infoHandler.sendInfo(msg1);
});
endpoint.getWebEndpoint().addIceGatheringDoneListener(event -> {
endpoint.kmsEvents.add(new KmsEvent(event));
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
});
endpoint.getWebEndpoint().addConnectionStateChangedListener(event -> {
endpoint.kmsEvents.add(new KmsEvent(event));
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
});
endpoint.getWebEndpoint().addNewCandidatePairSelectedListener(event -> {
endpoint.selectedLocalIceCandidate = event.getCandidatePair().getLocalCandidate();
endpoint.selectedRemoteIceCandidate = event.getCandidatePair().getRemoteCandidate();
endpoint.kmsEvents.add(new KmsEvent(event));
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
String msg = "ICE CANDIDATE SELECTED (" + endpoint.getEndpoint().getTag("name") + "): LOCAL CANDIDATE: "
+ endpoint.selectedLocalIceCandidate + " | REMOTE CANDIDATE: " + endpoint.selectedRemoteIceCandidate
+ " | TIMESTAMP: " + System.currentTimeMillis();
log.warn(msg);
this.infoHandler.sendInfo(msg);
});
endpoint.getEndpoint().addMediaTranscodingStateChangeListener(event -> {
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
});
endpoint.getWebEndpoint().addIceComponentStateChangeListener(event -> {
endpoint.kmsEvents.add(new KmsEvent(event, endpoint.createdAt()));
});
}
public MediaPipeline getPipeline() {

View File

@ -5,10 +5,15 @@ import org.kurento.client.MediaEvent;
public class KmsEvent {
long timestamp;
long msSinceCreation;
String endpoint;
MediaEvent event;
public KmsEvent(MediaEvent event) {
public KmsEvent(MediaEvent event, long createdAt) {
this.event = event;
this.endpoint = event.getSource().getTag("name");
this.event.setSource(null);
this.timestamp = System.currentTimeMillis();
this.msSinceCreation = this.timestamp - createdAt;
}
}

View File

@ -31,12 +31,14 @@ import org.kurento.client.EventListener;
import org.kurento.client.IceCandidate;
import org.kurento.client.ListenerSubscription;
import org.kurento.client.MediaElement;
import org.kurento.client.MediaEvent;
import org.kurento.client.MediaPipeline;
import org.kurento.client.MediaType;
import org.kurento.client.OnIceCandidateEvent;
import org.kurento.client.RtpEndpoint;
import org.kurento.client.SdpEndpoint;
import org.kurento.client.WebRtcEndpoint;
import org.kurento.jsonrpc.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -76,6 +78,7 @@ public abstract class MediaEndpoint {
private KurentoParticipant owner;
private String endpointName;
protected Long createdAt; // Timestamp when this [publisher / subscriber] started [publishing / receiving]
private MediaPipeline pipeline = null;
private ListenerSubscription endpointSubscription = null;
@ -157,6 +160,10 @@ public abstract class MediaEndpoint {
}
}
public long createdAt() {
return this.createdAt;
}
public WebRtcEndpoint getWebEndpoint() {
return webEndpoint;
}
@ -492,6 +499,7 @@ public abstract class MediaEndpoint {
public JsonObject withStatsToJson() {
JsonObject json = new JsonObject();
json.addProperty("createdAt", this.createdAt);
json.addProperty("webrtcTagName", this.getEndpoint().getTag("name"));
json.add("receivedCandidates", new GsonBuilder().create().toJsonTree(this.receivedCandidateList));
json.addProperty("localCandidate", this.selectedLocalIceCandidate);
@ -502,8 +510,13 @@ public abstract class MediaEndpoint {
JsonArray jsonArray = new JsonArray();
for (KmsEvent event : this.kmsEvents) {
JsonObject jsonKmsEvent = new JsonObject();
jsonKmsEvent.addProperty(event.event.getType(), event.timestamp);
JsonObject jsonKmsEvent = JsonUtils.toJsonObject(event.event);
// Set source name
jsonKmsEvent.addProperty("source", event.endpoint);
// Set custom more precise timestamp
jsonKmsEvent.addProperty("timestamp", event.timestamp);
// Set milliseconds since the Publisher or Subscriber started transmitting media
jsonKmsEvent.addProperty("msSinceCreation", event.msSinceCreation);
jsonArray.add(jsonKmsEvent);
}
json.add("events", jsonArray);

View File

@ -201,6 +201,7 @@ public class PublisherEndpoint extends MediaEndpoint {
throw new OpenViduException(Code.MEDIA_SDP_ERROR_CODE, "Sdp type not supported: " + sdpType);
}
gatherCandidates();
this.createdAt = System.currentTimeMillis();
return sdpResponse;
}
@ -580,7 +581,7 @@ public class PublisherEndpoint extends MediaEndpoint {
}
public String filterCollectionsToString() {
return "{filter: " + ((this.filter != null) ? this.filter.getName() : "null") + ", listener: " + this.filterListeners.toString()
+ ", subscribers: " + this.subscribersToFilterEvents.toString() + "}";
return "{filter: " + ((this.filter != null) ? this.filter.getName() : "null") + ", listener: "
+ this.filterListeners.toString() + ", subscribers: " + this.subscribersToFilterEvents.toString() + "}";
}
}

View File

@ -53,6 +53,7 @@ public class SubscriberEndpoint extends MediaEndpoint {
publisher.connect(this.getEndpoint());
setConnectedToPublisher(true);
setPublisher(publisher);
this.createdAt = System.currentTimeMillis();
return sdpAnswer;
}

View File

@ -35,7 +35,7 @@ import io.openvidu.server.config.OpenviduConfig;
public class ConfigRestController {
@Autowired
OpenviduConfig openviduConfig;
protected OpenviduConfig openviduConfig;
@RequestMapping(value = "/openvidu-publicurl", method = RequestMethod.GET)
public String getOpenViduPublicUrl() {