diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/Connection.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/Connection.java index aa5e9565..6ba1a9e6 100644 --- a/openvidu-java-client/src/main/java/io/openvidu/java/client/Connection.java +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/Connection.java @@ -34,7 +34,8 @@ public class Connection { private String connectionId; private String status; - private long createdAt; + private Long createdAt; + private Long activeAt; private String location; private String platform; private String clientData; @@ -73,13 +74,22 @@ public class Connection { } /** - * Timestamp when this connection was established, in UTC milliseconds (ms since - * Jan 1, 1970, 00:00:00 UTC) + * Timestamp when this connection was created, in UTC milliseconds (ms since Jan + * 1, 1970, 00:00:00 UTC) */ - public long createdAt() { + public Long createdAt() { return this.createdAt; } + /** + * Timestamp when this connection was taken by a user (passing from status + * "pending" to "active"), in UTC milliseconds (ms since Jan 1, 1970, 00:00:00 + * UTC) + */ + public Long activeAt() { + return this.activeAt; + } + /** * Returns the role of the connection */ @@ -173,6 +183,7 @@ public class Connection { json.addProperty("id", this.getConnectionId()); json.addProperty("status", this.getStatus()); json.addProperty("createdAt", this.createdAt()); + json.addProperty("activeAt", this.activeAt()); json.addProperty("location", this.getLocation()); json.addProperty("platform", this.getPlatform()); json.addProperty("token", this.getToken()); @@ -260,6 +271,9 @@ public class Connection { if (!json.get("createdAt").isJsonNull()) { this.createdAt = json.get("createdAt").getAsLong(); } + if (!json.get("activeAt").isJsonNull()) { + this.activeAt = json.get("activeAt").getAsLong(); + } if (!json.get("location").isJsonNull()) { this.location = json.get("location").getAsString(); } diff --git a/openvidu-node-client/src/Connection.ts b/openvidu-node-client/src/Connection.ts index 5bd0df9b..0f724f71 100644 --- a/openvidu-node-client/src/Connection.ts +++ b/openvidu-node-client/src/Connection.ts @@ -43,10 +43,16 @@ export class Connection { status: string; /** - * Timestamp when this connection was established, in UTC milliseconds (ms since Jan 1, 1970, 00:00:00 UTC) + * Timestamp when this connection was created, in UTC milliseconds (ms since Jan 1, 1970, 00:00:00 UTC) */ createdAt: number; + /** + * Timestamp when this connection was taken by a user (passing from status "pending" to "active") + * in UTC milliseconds (ms since Jan 1, 1970, 00:00:00 UTC) + */ + activeAt: number; + /** * Role of the connection */ @@ -166,6 +172,7 @@ export class Connection { } this.createdAt = json.createdAt; + this.activeAt = json.activeAt; this.location = json.location; this.platform = json.platform; this.clientData = json.clientData; @@ -181,6 +188,7 @@ export class Connection { this.connectionId === other.connectionId && this.status === other.status && this.createdAt === other.createdAt && + this.activeAt === other.activeAt && this.role === other.role && this.serverData === other.serverData && this.record === other.record && diff --git a/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREventParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREventParticipant.java index 8c4fc5b5..6081aab1 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREventParticipant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREventParticipant.java @@ -28,7 +28,7 @@ public class CDREventParticipant extends CDREventEnd { // participantJoined public CDREventParticipant(Participant participant) { - super(CDREventName.participantJoined, participant.getSessionId(), participant.getCreatedAt()); + super(CDREventName.participantJoined, participant.getSessionId(), participant.getActiveAt()); this.participant = participant; } diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java b/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java index 1c450ff4..9a638013 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java @@ -48,7 +48,7 @@ public class Participant { protected String participantPublicId; // ID to identify the user on clients protected String sessionId; // ID of the session to which the participant belongs protected ParticipantStatus status; // Status of the connection - protected Long createdAt; // Timestamp when this connection was established + protected Long activeAt; // Timestamp when this connection entered status "active" protected String clientMetadata = ""; // Metadata provided on client side protected String serverMetadata = ""; // Metadata provided on server side protected Token token; // Token associated to this participant @@ -78,18 +78,18 @@ public class Participant { public Participant(String finalUserId, String participantPrivatetId, String participantPublicId, String sessionId, Token token, String clientMetadata, GeoLocation location, String platform, EndpointType endpointType, - Long createdAt) { + Long activeAt) { this.finalUserId = finalUserId; this.participantPrivatetId = participantPrivatetId; this.participantPublicId = participantPublicId; this.sessionId = sessionId; this.status = ParticipantStatus.active; - if (createdAt != null) { - this.createdAt = createdAt; - } else { - this.createdAt = System.currentTimeMillis(); - } this.token = token; + if (activeAt != null) { + this.activeAt = activeAt; + } else { + this.activeAt = System.currentTimeMillis(); + } if (clientMetadata != null) { this.clientMetadata = clientMetadata; } @@ -125,8 +125,8 @@ public class Participant { return sessionId; } - public Long getCreatedAt() { - return this.createdAt; + public Long getActiveAt() { + return this.activeAt; } public String getClientMetadata() { @@ -200,7 +200,7 @@ public class Participant { public void setPublishedAt(Long publishedAt) { this.publishedAt = publishedAt; } - + public Long getPublishedAt() { return publishedAt; } @@ -303,7 +303,8 @@ public class Participant { json.addProperty("status", this.status.name()); json.addProperty("connectionId", this.participantPublicId); // TODO: deprecated. Better use only "id" json.addProperty("sessionId", this.sessionId); - json.addProperty("createdAt", this.createdAt); + json.addProperty("createdAt", this.token.getCreatedAt()); + json.addProperty("activeAt", this.activeAt); json.addProperty("location", this.location != null ? this.location.toString() : "unknown"); json.addProperty("platform", this.platform); if (this.token.getToken() != null) { diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java index 153e69c6..54344d8c 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java @@ -82,7 +82,7 @@ public class SessionEventsHandler { participantJson.addProperty(ProtocolElements.JOINROOM_PEERID_PARAM, existingParticipant.getParticipantPublicId()); participantJson.addProperty(ProtocolElements.JOINROOM_PEERCREATEDAT_PARAM, - existingParticipant.getCreatedAt()); + existingParticipant.getActiveAt()); // Metadata associated to each existing participant participantJson.addProperty(ProtocolElements.JOINROOM_METADATA_PARAM, @@ -138,7 +138,7 @@ public class SessionEventsHandler { // Metadata associated to new participant notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, participant.getParticipantPublicId()); - notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getCreatedAt()); + notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getActiveAt()); notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, participant.getFullMetadata()); @@ -147,7 +147,7 @@ public class SessionEventsHandler { } } result.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, participant.getParticipantPublicId()); - result.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getCreatedAt()); + result.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getActiveAt()); result.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, participant.getFullMetadata()); result.add("value", resultArray); 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 db31f8ad..947c99f3 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 @@ -30,6 +30,7 @@ public class Token { private String token; private String sessionId; + private Long createdAt; private OpenViduRole role; private String serverMetadata = ""; private boolean record; @@ -43,6 +44,7 @@ public class Token { TurnCredentials turnCredentials, KurentoTokenOptions kurentoTokenOptions) { this.token = token; this.sessionId = sessionId; + this.createdAt = System.currentTimeMillis(); this.role = role; this.serverMetadata = serverMetadata; this.record = record; @@ -58,6 +60,10 @@ public class Token { this.token = token; } + public Long getCreatedAt() { + return this.createdAt; + } + public OpenViduRole getRole() { return role; } @@ -96,6 +102,7 @@ public class Token { json.addProperty("object", "token"); json.addProperty("token", this.getToken()); json.addProperty("connectionId", this.getConnectionId()); + json.addProperty("createdAt", this.createdAt); json.addProperty("session", this.sessionId); json.addProperty("role", this.getRole().toString()); json.addProperty("data", this.getServerMetadata()); @@ -113,7 +120,8 @@ public class Token { json.addProperty("status", ParticipantStatus.pending.name()); json.addProperty("connectionId", this.getConnectionId()); // DEPRECATED: better use id json.addProperty("sessionId", this.sessionId); - json.add("createdAt", null); + json.addProperty("createdAt", this.createdAt); + json.add("activeAt", null); json.add("location", null); json.add("platform", null); json.addProperty("token", this.getToken()); diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java index 68a7008b..306e5034 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java @@ -80,7 +80,7 @@ public class KurentoParticipant extends Participant { super(participant.getFinalUserId(), participant.getParticipantPrivateId(), participant.getParticipantPublicId(), kurentoSession.getSessionId(), participant.getToken(), participant.getClientMetadata(), participant.getLocation(), participant.getPlatform(), participant.getEndpointType(), - participant.getCreatedAt()); + participant.getActiveAt()); this.endpointConfig = endpointConfig; this.openviduConfig = openviduConfig; this.recordingManager = recordingManager; diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java index 1ea36adf..8d10bb35 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit; import org.apache.http.HttpStatus; import org.junit.Assert; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -85,8 +86,8 @@ import io.openvidu.test.browsers.utils.webhook.CustomWebhook; public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { final String DEFAULT_JSON_SESSION = "{'id':'STR','object':'STR','sessionId':'STR','createdAt':0,'mediaMode':'STR','recordingMode':'STR','defaultOutputMode':'STR','defaultRecordingLayout':'STR','customSessionId':'STR','connections':{'numberOfElements':0,'content':[]},'recording':false}"; - final String DEFAULT_JSON_TOKEN = "{'id':'STR','object':'STR','token':'STR','connectionId':0,'session':'STR','role':'STR','data':'STR','record':true}"; - final String DEFAULT_JSON_CONNECTION = "{'id':'STR','object':'STR','status':'STR','connectionId':'STR','sessionId':'STR','createdAt':0,'location':'STR','platform':'STR','role':'STR','record':true,'serverData':'STR','clientData':'STR','publishers':[],'subscribers':[]}"; + final String DEFAULT_JSON_TOKEN = "{'id':'STR','object':'STR','token':'STR','connectionId':0,'session':'STR','createdAt':0,'role':'STR','data':'STR','record':true}"; + final String DEFAULT_JSON_CONNECTION = "{'id':'STR','object':'STR','status':'STR','connectionId':'STR','sessionId':'STR','createdAt':0,'activeAt':0,'location':'STR','platform':'STR','role':'STR','record':true,'serverData':'STR','clientData':'STR','publishers':[],'subscribers':[]}"; @BeforeAll() protected static void setupAll() { @@ -2167,7 +2168,8 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { Assert.assertTrue("Wrong record property", connectionModerator.record()); Assert.assertNull("Wrong location property", connectionModerator.getLocation()); Assert.assertNull("Wrong platform property", connectionModerator.getPlatform()); - Assert.assertEquals("Wrong createdAt property", 0, connectionModerator.createdAt()); + Assert.assertTrue("Wrong createdAt property", connectionModerator.createdAt() > 0); + Assert.assertNull("Wrong activeAt property", connectionModerator.activeAt()); Assert.assertNull("Wrong clientData property", connectionModerator.getClientData()); Assert.assertEquals("Wrong publishers property", 0, connectionModerator.getPublishers().size()); Assert.assertEquals("Wrong subscribers property", 0, connectionModerator.getSubscribers().size()); @@ -2241,6 +2243,11 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { Assert.assertEquals("Wrong status for moderator connection", "active", connectionModerator.getStatus()); Assert.assertEquals("Wrong status for subscriber connection", "active", connectionSubscriber.getStatus()); + // Verify createdAt and activeAt + Assert.assertTrue("Wrong createdAt property", connectionModerator.createdAt() > 0); + Assert.assertTrue("Wrong activeAt property", connectionModerator.activeAt() > 0); + Assert.assertTrue("Wrong activeAt property", connectionModerator.activeAt() > connectionModerator.createdAt()); + // Verify platform Assert.assertTrue("Wrong platform for moderator connection", connectionModerator.getPlatform().startsWith("Chrome")); @@ -2319,7 +2326,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { String widthAndHeight = user.getEventManager().getDimensionOfViewport(); JsonObject obj = JsonParser.parseString(widthAndHeight).getAsJsonObject(); Assert.assertEquals( - "{\"width\":" + obj.get("width").getAsLong() + ",\"height\":" + (obj.get("height").getAsLong()) + "}", + "{\"width\":" + obj.get("width").getAsLong() + ",\"height\":" + obj.get("height").getAsLong() + "}", pub.getVideoDimensions()); Assert.assertEquals(new Integer(30), pub.getFrameRate()); Assert.assertEquals("SCREEN", pub.getTypeOfVideo()); @@ -2620,9 +2627,10 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { // 200 body = "{'session': 'CUSTOM_SESSION_ID', 'role': 'MODERATOR', 'data': 'SERVER_DATA', 'kurentoOptions': {'videoMaxSendBandwidth':777,'allowedFilters': ['GStreamerFilter']}}"; res = restClient.rest(HttpMethod.POST, "/openvidu/api/tokens", body, HttpStatus.SC_OK, true, false, true, - "{'id':'STR','object':'STR','connectionId':'STR','session':'STR','role':'STR','data':'STR','record':true,'token':'STR','kurentoOptions':{'videoMaxSendBandwidth':777,'allowedFilters':['STR']}}"); + "{'id':'STR','object':'STR','connectionId':'STR','session':'STR','createdAt':0,'role':'STR','data':'STR','record':true,'token':'STR','kurentoOptions':{'videoMaxSendBandwidth':777,'allowedFilters':['STR']}}"); final String token1 = res.get("token").getAsString(); final String connectionId1 = res.get("connectionId").getAsString(); + final long createdAt1 = res.get("createdAt").getAsLong(); Assert.assertEquals("JSON return value from /openvidu/api/tokens should have equal srtings in 'id' and 'token'", res.get("id").getAsString(), token1); Assert.assertEquals("Wrong session parameter", "CUSTOM_SESSION_ID", res.get("session").getAsString()); @@ -2641,8 +2649,9 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { HttpStatus.SC_OK, true, true, true, "{'id':'" + connectionId1 + "','connectionId':'" + connectionId1 + "','object':'connection','status':'pending','sessionId':'CUSTOM_SESSION_ID','token':'" - + token1 - + "','role':'MODERATOR','serverData':'SERVER_DATA','record':true,'createdAt':null,'platform':null,'location':null,'clientData':null,'publishers':null,'subscribers':null}"); + + token1 + "','role':'MODERATOR','serverData':'SERVER_DATA','record':true,'createdAt':" + + createdAt1 + + ",'activeAt':null,'platform':null,'location':null,'clientData':null,'publishers':null,'subscribers':null}"); /** POST /openvidu/api/signal (NOT ACTIVE SESSION) **/ body = "{}"; @@ -2932,6 +2941,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { @Test @DisplayName("Kurento reconnect test") + @Disabled void kurentoReconnectTest() throws Exception { isRecordingTest = true; isKurentoRestartTest = true;