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 6dbf9a12..c29398d5 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 @@ -285,6 +285,10 @@ public class SessionRestController { return this.generateErrorResponse("Type error in some parameter", "/api/tokens", HttpStatus.BAD_REQUEST); } + if (sessionId == null) { + return this.generateErrorResponse("Type error in some parameter", "/api/tokens", HttpStatus.BAD_REQUEST); + } + JsonObject kurentoOptions = null; if (params.get("kurentoOptions") != null) { @@ -369,6 +373,11 @@ public class SessionRestController { log.info("REST API: POST /api/recordings/start {}", params.toString()); + if (!this.openviduConfig.isRecordingModuleEnabled()) { + // OpenVidu Server configuration property "openvidu.recording" is set to false + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + String sessionId; String name; String outputModeString; @@ -397,81 +406,83 @@ public class SessionRestController { HttpStatus.BAD_REQUEST); } - if (!this.openviduConfig.isRecordingModuleEnabled()) { - // OpenVidu Server configuration property "openvidu.recording" is set to false - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + io.openvidu.java.client.Recording.OutputMode finalOutputMode = null; + RecordingLayout recordingLayout = null; + if (outputModeString != null && !outputModeString.isEmpty()) { + try { + finalOutputMode = io.openvidu.java.client.Recording.OutputMode.valueOf(outputModeString); + } catch (Exception e) { + return this.generateErrorResponse("Type error in some parameter", "/api/recordings/start", + HttpStatus.BAD_REQUEST); + } + } + if (io.openvidu.java.client.Recording.OutputMode.COMPOSED.equals(finalOutputMode)) { + if (resolution != null && !sessionManager.formatChecker.isAcceptableRecordingResolution(resolution)) { + return this.generateErrorResponse( + "Wrong \"resolution\" parameter. Acceptable values from 100 to 1999 for both width and height", + "/api/recordings/start", HttpStatus.UNPROCESSABLE_ENTITY); + } + if (recordingLayoutString != null && !recordingLayoutString.isEmpty()) { + try { + recordingLayout = RecordingLayout.valueOf(recordingLayoutString); + } catch (Exception e) { + return this.generateErrorResponse("Type error in some parameter", "/api/recordings/start", + HttpStatus.BAD_REQUEST); + } + } + } + if ((hasAudio != null && hasVideo != null) && !hasAudio && !hasVideo) { + // Cannot start a recording with both "hasAudio" and "hasVideo" to false + return this.generateErrorResponse( + "Cannot start a recording with both \"hasAudio\" and \"hasVideo\" set to false", + "/api/recordings/start", HttpStatus.UNPROCESSABLE_ENTITY); } Session session = sessionManager.getSession(sessionId); - if (session == null) { - if (sessionManager.getSessionNotActive(sessionId) != null) { - // Session is not active - return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); + session = sessionManager.getSessionNotActive(sessionId); + if (session != null) { + if (!(MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode())) + || this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) { + // Session is not in ROUTED MediMode or it is already being recorded + return new ResponseEntity<>(HttpStatus.CONFLICT); + } else { + // Session is not active + return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); + } } // Session does not exist return new ResponseEntity<>(HttpStatus.NOT_FOUND); } + if (!(MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode())) + || this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) { + // Session is not in ROUTED MediMode or it is already being recorded + return new ResponseEntity<>(HttpStatus.CONFLICT); + } if (session.getParticipants().isEmpty()) { // Session has no participants return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); } - if (!(session.getSessionProperties().mediaMode().equals(MediaMode.ROUTED)) - || this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) { - // Session is not in ROUTED MediMode or it is already being recorded - return new ResponseEntity<>(HttpStatus.CONFLICT); + + RecordingProperties.Builder builder = new RecordingProperties.Builder(); + if (finalOutputMode == null) { + builder.outputMode(session.getSessionProperties().defaultOutputMode()); } - - io.openvidu.java.client.Recording.OutputMode outputMode; - try { - outputMode = io.openvidu.java.client.Recording.OutputMode.valueOf(outputModeString); - } catch (Exception e) { - outputMode = session.getSessionProperties().defaultOutputMode(); - } - RecordingProperties.Builder builder = new RecordingProperties.Builder().name(name).outputMode(outputMode) - .hasAudio(hasAudio != null ? hasAudio : true).hasVideo(hasVideo != null ? hasVideo : true); - - if (outputMode.equals(io.openvidu.java.client.Recording.OutputMode.COMPOSED)) { - + if (io.openvidu.java.client.Recording.OutputMode.COMPOSED.equals(finalOutputMode)) { if (resolution != null) { - if (sessionManager.formatChecker.isAcceptableRecordingResolution(resolution)) { - builder.resolution(resolution); - } else { - return new ResponseEntity<>( - "Wrong \"resolution\" parameter. Acceptable values from 100 to 1999 for both width and height", - HttpStatus.UNPROCESSABLE_ENTITY); - } + builder.resolution(resolution); } - - RecordingLayout recordingLayout; - if (recordingLayoutString == null || recordingLayoutString.isEmpty()) { - // "recordingLayout" parameter not defined. Use global layout from - // SessionProperties (it is always configured as it has RecordingLayout.BEST_FIT - // as default value) - recordingLayout = session.getSessionProperties().defaultRecordingLayout(); - } else { - recordingLayout = RecordingLayout.valueOf(recordingLayoutString); - } - - builder.recordingLayout(recordingLayout); - + builder.recordingLayout(recordingLayout == null ? session.getSessionProperties().defaultRecordingLayout() + : recordingLayout); if (RecordingLayout.CUSTOM.equals(recordingLayout)) { - customLayout = (customLayout == null || customLayout.isEmpty()) - ? session.getSessionProperties().defaultCustomLayout() - : customLayout; - builder.customLayout(customLayout); + builder.customLayout( + customLayout == null ? session.getSessionProperties().defaultCustomLayout() : customLayout); } } - - RecordingProperties properties = builder.build(); - if (!properties.hasAudio() && !properties.hasVideo()) { - // Cannot start a recording with both "hasAudio" and "hasVideo" to false - return new ResponseEntity<>("Cannot start a recording with both \"hasAudio\" and \"hasVideo\" set to false", - HttpStatus.UNPROCESSABLE_ENTITY); - } + builder.name(name).hasAudio(hasAudio != null ? hasAudio : true).hasVideo(hasVideo != null ? hasVideo : true); try { - Recording startedRecording = this.recordingManager.startRecording(session, properties); + Recording startedRecording = this.recordingManager.startRecording(session, builder.build()); return new ResponseEntity<>(startedRecording.toJson().toString(), getResponseHeaders(), HttpStatus.OK); } catch (OpenViduException e) { return new ResponseEntity<>("Error starting recording: " + e.getMessage(), getResponseHeaders(), @@ -484,11 +495,6 @@ public class SessionRestController { log.info("REST API: POST /api/recordings/stop/{}", recordingId); - if (recordingId == null) { - // "recordingId" parameter not found - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - Recording recording = recordingManager.getStartedRecording(recordingId); if (recording == null) { 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 b75e559c..520eff25 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 @@ -268,7 +268,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -296,7 +296,7 @@ public class OpenViduTestAppE2eTest { System.out.println(this.getBase64Screenshot(user)); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to only have audio tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, false)); @@ -322,7 +322,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to only have video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true)); @@ -346,7 +346,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -371,7 +371,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 1); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertTrue("Video was expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -396,7 +396,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 1); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertTrue("Video was expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -422,7 +422,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 1); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertTrue("Video was expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -450,7 +450,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 16); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 16 videos but found " + numberOfVideos, numberOfVideos, 16); + Assert.assertEquals("Expected 16 videos but found " + numberOfVideos, 16, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -474,7 +474,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -520,7 +520,7 @@ public class OpenViduTestAppE2eTest { user2.getEventManager().waitUntilEventReaches("streamPlaying", 2); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -547,7 +547,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 2); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -604,7 +604,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 2); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -622,7 +622,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 3); numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -670,7 +670,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -747,7 +747,7 @@ public class OpenViduTestAppE2eTest { } int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -781,7 +781,7 @@ public class OpenViduTestAppE2eTest { } numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to only have audio tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true)); @@ -814,7 +814,7 @@ public class OpenViduTestAppE2eTest { } numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -854,7 +854,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 3); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, numberOfVideos, 3); + Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, 3, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -864,7 +864,7 @@ public class OpenViduTestAppE2eTest { List videos = user.getDriver().findElements(By.tagName("video")); numberOfVideos = videos.size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertFalse("Publisher video should not have srcObject defined after force unpublish", user.getEventManager().hasMediaStream(videos.get(0), "")); @@ -874,7 +874,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 6); numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, numberOfVideos, 3); + Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, 3, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1021,7 +1021,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 1); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertTrue("Video was expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1113,7 +1113,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 1); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 1 video but found " + numberOfVideos, numberOfVideos, 1); + Assert.assertEquals("Expected 1 video but found " + numberOfVideos, 1, numberOfVideos); Assert.assertTrue("Video was expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1230,7 +1230,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1369,7 +1369,8 @@ public class OpenViduTestAppE2eTest { user2.getEventManager().waitUntilEventReaches("streamCreated", 8); user2.getEventManager().waitUntilEventReaches("streamPlaying", 8); - Assert.assertEquals(user2.getDriver().findElements(By.tagName("video")).size(), 8); + int nVideos = user2.getDriver().findElements(By.tagName("video")).size(); + Assert.assertEquals("Expected 8 videos in Firefox user but found " + nVideos, 8, nVideos); user2.getEventManager().waitUntilEventReaches("recordingStarted", 2); user2.getEventManager().waitUntilEventReaches("recordingStopped", 2); @@ -1416,7 +1417,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 8); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 8 videos but found " + numberOfVideos, numberOfVideos, 8); + Assert.assertEquals("Expected 8 videos but found " + numberOfVideos, 8, numberOfVideos); user.getDriver().findElement(By.id("session-api-btn-0")).click(); Thread.sleep(1000); @@ -1587,7 +1588,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 4); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, numberOfVideos, 4); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1625,7 +1626,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamDestroyed", 2); numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, numberOfVideos, 3); + Assert.assertEquals("Expected 3 videos but found " + numberOfVideos, 3, numberOfVideos); // Force disconnect wrong user.getDriver().findElement(By.id("resource-id-field")).clear(); @@ -1686,7 +1687,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 2); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have a video only track", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true)); @@ -1837,7 +1838,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 2); int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have only a video track", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), false, true)); @@ -1927,7 +1928,7 @@ public class OpenViduTestAppE2eTest { Assert.assertFalse("OV.fetch() should return false if OV.createSession() has not been called", OV.fetch()); List sessions = OV.getActiveSessions(); - Assert.assertEquals("Expected no active sessions but found " + sessions.size(), sessions.size(), 0); + Assert.assertEquals("Expected no active sessions but found " + sessions.size(), 0, sessions.size()); SessionProperties properties = new SessionProperties.Builder().customSessionId(customSessionId) .mediaMode(MediaMode.ROUTED).recordingMode(RecordingMode.ALWAYS) @@ -1980,7 +1981,7 @@ public class OpenViduTestAppE2eTest { user.getEventManager().waitUntilEventReaches("streamPlaying", 2); final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); - Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, numberOfVideos, 2); + Assert.assertEquals("Expected 2 videos but found " + numberOfVideos, 2, numberOfVideos); Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); @@ -1996,12 +1997,14 @@ public class OpenViduTestAppE2eTest { @DisplayName("REST API test") void restApiTest() throws Exception { + log.info("REST API test"); + CustomHttpClient restClient = new CustomHttpClient(OPENVIDU_URL, OPENVIDU_SECRET); // 401 restClient.testAuthorizationError(); - // GET /api/sessions before any session created + /** GET /api/sessions (before session created) **/ restClient.rest(HttpMethod.GET, "/api/sessions/NOT_EXISTS", HttpStatus.SC_NOT_FOUND); Map returnValues = new HashMap<>(); returnValues.put("numberOfElements", new Integer(0)); @@ -2010,11 +2013,11 @@ public class OpenViduTestAppE2eTest { /** POST /api/sessions **/ // 400 - String body = "{'mediaMode': 'ROUTED', 'recordingMode': 'ALWAYS', 'customSessionId': 999}"; + String body = "{'mediaMode': 'NOT_EXISTS'}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_BAD_REQUEST); body = "{'mediaMode': 'ROUTED', 'recordingMode': false}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_BAD_REQUEST); - body = "{'mediaMode': 'NOT_EXISTS'}"; + body = "{'mediaMode': 'ROUTED', 'recordingMode': 'ALWAYS', 'customSessionId': 999}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_BAD_REQUEST); body = "{'mediaMode': 'ROUTED', 'recordingMode': 'NOT_EXISTS'}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_BAD_REQUEST); @@ -2024,17 +2027,21 @@ public class OpenViduTestAppE2eTest { restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_BAD_REQUEST); // 200 - body = "{'mediaMode': 'ROUTED', 'recordingMode': 'ALWAYS', 'customSessionId': 'CUSTOM_SESSION_ID', 'defaultOutputMode': 'INDIVIDUAL', 'defaultRecordingLayout': 'BEST_FIT'}"; + body = "{'mediaMode': 'ROUTED', 'recordingMode': 'MANUAL', 'customSessionId': 'CUSTOM_SESSION_ID', 'defaultOutputMode': 'COMPOSED', 'defaultRecordingLayout': 'BEST_FIT'}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_OK, true, "{'id': 'STR', 'createdAt': 0}"); + // Default values + org.json.JSONObject res = restClient.rest(HttpMethod.POST, "/api/sessions", "{}", HttpStatus.SC_OK, true, + "{'id': 'STR', 'createdAt': 0}"); + restClient.rest(HttpMethod.DELETE, "/api/sessions/" + res.getString("id"), HttpStatus.SC_NO_CONTENT); // 409 body = "{'customSessionId': 'CUSTOM_SESSION_ID'}"; restClient.rest(HttpMethod.POST, "/api/sessions", body, HttpStatus.SC_CONFLICT); - // GET /api/sessions after session created + /** GET /api/sessions (after session created) **/ restClient.rest(HttpMethod.GET, "/api/sessions/CUSTOM_SESSION_ID", null, HttpStatus.SC_OK, true, - "{'sessionId':'STR','createdAt':0,'mediaMode':'STR','recordingMode':'STR','defaultOutputMode':'STR','customSessionId':'STR','connections':{'numberOfElements':0,'content':[]},'recording':true}"); + "{'sessionId':'STR','createdAt':0,'mediaMode':'STR','recordingMode':'STR','defaultOutputMode':'STR','defaultRecordingLayout':'STR','customSessionId':'STR','connections':{'numberOfElements':0,'content':[]},'recording':true}"); returnValues = new HashMap<>(); returnValues.put("numberOfElements", new Integer(1)); returnValues.put("content", new org.json.JSONArray()); @@ -2042,9 +2049,11 @@ public class OpenViduTestAppE2eTest { /** POST /api/tokens **/ // 400 + body = "{}"; + restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_BAD_REQUEST); body = "{'session': true}"; restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_BAD_REQUEST); - body = "{'session': 'CUSTOM_SESSION_ID', 'role': 'NOT_EXISTS', 'data': 'DATA'}"; + body = "{'session': 'CUSTOM_SESSION_ID', 'role': 'NOT_EXISTS'}"; restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_BAD_REQUEST); body = "{'session': 'CUSTOM_SESSION_ID', 'role': 'MODERATOR', 'data': 999}"; restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_BAD_REQUEST); @@ -2055,7 +2064,176 @@ public class OpenViduTestAppE2eTest { // 200 body = "{'session': 'CUSTOM_SESSION_ID', 'role': 'MODERATOR', 'data': 'SERVER_DATA', 'kurentoOptions': {'allowedFilters': ['GStreamerFilter']}}"; - restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_OK); + res = restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_OK, true, + "{'id':'STR','session':'STR','role':'STR','data':'STR','token':'STR','kurentoOptions':{'allowedFilters':['STR']}}"); + final String token1 = res.getString("token"); + Assert.assertEquals("JSON return value from /api/tokens should have equal srtings in 'id' and 'token'", + res.getString("id"), token1); + Assert.assertEquals("Wrong session parameter", "CUSTOM_SESSION_ID", res.getString("session")); + + // Default values + body = "{'session': 'CUSTOM_SESSION_ID'}"; + res = restClient.rest(HttpMethod.POST, "/api/tokens", body, HttpStatus.SC_OK, true, + "{'id':'STR','session':'STR','role':'STR','data':'STR','token':'STR'}"); + final String token2 = res.getString("id"); + + /** POST /api/recordings/start (NOT ACTIVE SESSION) **/ + // 400 + body = "{}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + body = "{'session': true}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + body = "{'session':'SESSION_ID','name':999}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + body = "{'session':'SESSION_ID','name':'NAME','outputMode':'NOT_EXISTS'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + body = "{'session':'SESSION_ID','name':'NAME','outputMode':'COMPOSED','recordingLayout':'NOT_EXISTS'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + body = "{'session':'SESSION_ID','name':'NAME','outputMode':'COMPOSED','recordingLayout':'BEST_FIT','customLayout':'CUSTOM_LAYOUT','hasAudio':true,'hasVideo':true,'resolution':999}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_BAD_REQUEST); + + // 422 + body = "{'session':'SESSION_ID','name':'NAME','outputMode':'COMPOSED','recordingLayout':'BEST_FIT','customLayout':'CUSTOM_LAYOUT','hasAudio':false,'hasVideo':false}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_UNPROCESSABLE_ENTITY); + body = "{'session':'SESSION_ID','name':'NAME','outputMode':'COMPOSED','recordingLayout':'BEST_FIT','customLayout':'CUSTOM_LAYOUT','hasAudio':true,'hasVideo':true,'resolution':'1920x2000'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_UNPROCESSABLE_ENTITY); + + // 404 + body = "{'session':'SESSION_ID'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_NOT_FOUND); + + // 406 + body = "{'session':'CUSTOM_SESSION_ID'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_NOT_ACCEPTABLE); + + // 409 (RELAYED media mode) + res = restClient.rest(HttpMethod.POST, "/api/sessions", "{'mediaMode':'RELAYED'}", HttpStatus.SC_OK, true, + "{'id': 'STR', 'createdAt': 0}"); + body = "{'session':'" + res.getString("id") + "'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_CONFLICT); + restClient.rest(HttpMethod.DELETE, "/api/sessions/" + res.getString("id"), HttpStatus.SC_NO_CONTENT); + + // Start session + setupBrowser("chrome"); + user.getDriver().findElement(By.id("one2one-btn")).click(); + user.getDriver().findElement(By.id("session-settings-btn-0")).click(); + Thread.sleep(1000); + + // Set token 1 + WebElement tokeInput = user.getDriver().findElement(By.cssSelector("#custom-token-div input")); + tokeInput.clear(); + tokeInput.sendKeys(token1); + + user.getDriver().findElement(By.id("save-btn")).click(); + Thread.sleep(1000); + user.getDriver().findElement(By.id("session-settings-btn-1")).click(); + Thread.sleep(1000); + + // Set token 2 + tokeInput = user.getDriver().findElement(By.cssSelector("#custom-token-div input")); + tokeInput.clear(); + tokeInput.sendKeys(token2); + user.getDriver().findElement(By.id("save-btn")).click(); + Thread.sleep(1000); + + user.getDriver().findElements(By.className("join-btn")).forEach(el -> el.sendKeys(Keys.ENTER)); + + user.getEventManager().waitUntilEventReaches("connectionCreated", 4); + user.getEventManager().waitUntilEventReaches("accessAllowed", 2); + user.getEventManager().waitUntilEventReaches("streamCreated", 4); + user.getEventManager().waitUntilEventReaches("streamPlaying", 4); + + final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size(); + Assert.assertEquals("Expected 4 videos but found " + numberOfVideos, 4, numberOfVideos); + Assert.assertTrue("Videos were expected to have audio and video tracks", user.getEventManager() + .assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); + + /** GET /api/recordings (before recording started) **/ + restClient.rest(HttpMethod.GET, "/api/recordings/NOT_EXISTS", HttpStatus.SC_NOT_FOUND); + returnValues = new HashMap<>(); + returnValues.put("count", new Integer(0)); + returnValues.put("items", "[]"); + restClient.rest(HttpMethod.GET, "/api/recordings", null, HttpStatus.SC_OK, true, returnValues); + + /** POST /api/recordings/start (ACTIVE SESSION) **/ + // 200 + body = "{'session':'CUSTOM_SESSION_ID'}"; + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_OK, true, + "{'id':'STR','sessionId':'STR','name':'STR','outputMode':'STR','recordingLayout':'STR','hasAudio':false,'hasVideo':false,'resolution':'STR','createdAt':0,'size':0,'duration':0,'url':null,'status':'STR'}"); + + // 409 (already recording) + restClient.rest(HttpMethod.POST, "/api/recordings/start", body, HttpStatus.SC_CONFLICT); + + /** POST /api/recordings/stop **/ + // 405 + restClient.rest(HttpMethod.POST, "/api/recordings/stop", body, HttpStatus.SC_METHOD_NOT_ALLOWED); + + // 404 + restClient.rest(HttpMethod.POST, "/api/recordings/stop/NOT_EXISTS", body, HttpStatus.SC_NOT_FOUND); + + // 200 + restClient.rest(HttpMethod.DELETE, "/api/recordings/CUSTOM_SESSION_ID", HttpStatus.SC_CONFLICT); + restClient.rest(HttpMethod.POST, "/api/recordings/stop/CUSTOM_SESSION_ID", body, HttpStatus.SC_OK, true, + "{'id':'STR','sessionId':'STR','name':'STR','outputMode':'STR','recordingLayout':'STR','hasAudio':false,'hasVideo':false,'resolution':'STR','createdAt':0,'size':0,'duration':0,'url':null,'status':'STR'}"); + /** GET /api/recordings (after recording created) **/ + restClient.rest(HttpMethod.GET, "/api/recordings/CUSTOM_SESSION_ID", null, HttpStatus.SC_OK, true, + "{'id':'STR','sessionId':'STR','name':'STR','outputMode':'STR','hasAudio':false,'hasVideo':false,'createdAt':0,'size':0,'duration':0,'url':null,'status':'STR'}"); + returnValues = new HashMap<>(); + returnValues.put("count", new Integer(1)); + returnValues.put("items", new org.json.JSONArray()); + restClient.rest(HttpMethod.GET, "/api/recordings", null, HttpStatus.SC_OK, true, returnValues); + + /** DELETE /api/recordings **/ + restClient.rest(HttpMethod.DELETE, "/api/recordings", HttpStatus.SC_METHOD_NOT_ALLOWED); + restClient.rest(HttpMethod.DELETE, "/api/recordings/NOT_EXISTS", HttpStatus.SC_NOT_FOUND); + restClient.rest(HttpMethod.DELETE, "/api/recordings/CUSTOM_SESSION_ID", HttpStatus.SC_NO_CONTENT); + + // GET /api/recordings should return empty again + returnValues = new HashMap<>(); + returnValues.put("count", new Integer(0)); + returnValues.put("items", "[]"); + restClient.rest(HttpMethod.GET, "/api/recordings", null, HttpStatus.SC_OK, true, returnValues); + + /** DELETE /api/sessions//stream/ **/ + restClient.rest(HttpMethod.DELETE, "/api/sessions/NOT_EXISTS/stream/NOT_EXISTS", HttpStatus.SC_BAD_REQUEST); + restClient.rest(HttpMethod.DELETE, "/api/sessions/CUSTOM_SESSION_ID/stream/NOT_EXISTS", + HttpStatus.SC_NOT_FOUND); + res = restClient.rest(HttpMethod.GET, "/api/sessions/CUSTOM_SESSION_ID", null, HttpStatus.SC_OK, true, + "{'sessionId':'STR','createdAt':0,'mediaMode':'STR','recordingMode':'STR','defaultOutputMode':'STR','defaultRecordingLayout':'STR','customSessionId':'STR','connections':{'numberOfElements':2,'content'" + + ":[{'connectionId':'STR','createdAt':0,'location':'STR','platform':'STR','token':'STR','role':'STR','serverData':'STR','clientData':'STR','publishers':[" + + "{'createdAt':0,'streamId':'STR','mediaOptions':{'hasAudio':false,'audioActive':false,'hasVideo':false,'videoActive':false,'typeOfVideo':'STR','frameRate':0," + + "'videoDimensions':'STR','filter':{}}}],'subscribers':[{'createdAt':0,'streamId':'STR','publisher':'STR'}]},{'connectionId':'STR','createdAt':0,'location':'STR'," + + "'platform':'STR','token':'STR','role':'STR','serverData':'STR','clientData':'STR','publishers':[{'createdAt':0,'streamId':'STR','mediaOptions':{'hasAudio':false," + + "'audioActive':false,'hasVideo':false,'videoActive':false,'typeOfVideo':'STR','frameRate':0,'videoDimensions':'STR','filter':{}}}],'subscribers':[{'createdAt':0,'streamId':'STR','publisher':'STR'}]}]},'recording':false}"); + String streamId = ((org.json.JSONObject) ((org.json.JSONObject) res.getJSONObject("connections") + .getJSONArray("content").get(0)).getJSONArray("publishers").get(0)).getString("streamId"); + restClient.rest(HttpMethod.DELETE, "/api/sessions/CUSTOM_SESSION_ID/stream/" + streamId, + HttpStatus.SC_NO_CONTENT); + + /** DELETE /api/sessions//connection/ **/ + restClient.rest(HttpMethod.DELETE, "/api/sessions/NOT_EXISTS/connection/NOT_EXISTS", HttpStatus.SC_BAD_REQUEST); + restClient.rest(HttpMethod.DELETE, "/api/sessions/CUSTOM_SESSION_ID/connection/NOT_EXISTS", + HttpStatus.SC_NOT_FOUND); + String connectionId = ((org.json.JSONObject) res.getJSONObject("connections").getJSONArray("content").get(0)) + .getString("connectionId"); + restClient.rest(HttpMethod.DELETE, "/api/sessions/CUSTOM_SESSION_ID/connection/" + connectionId, + HttpStatus.SC_NO_CONTENT); + + /** DELETE /api/sessions **/ + restClient.rest(HttpMethod.DELETE, "/api/sessions", HttpStatus.SC_METHOD_NOT_ALLOWED); + restClient.rest(HttpMethod.DELETE, "/api/sessions/NOT_EXISTS", HttpStatus.SC_NOT_FOUND); + restClient.rest(HttpMethod.DELETE, "/api/sessions/CUSTOM_SESSION_ID", HttpStatus.SC_NO_CONTENT); + + // GET /api/sessions should return empty again + returnValues = new HashMap<>(); + returnValues.put("numberOfElements", new Integer(0)); + returnValues.put("content", "[]"); + restClient.rest(HttpMethod.GET, "/api/sessions", null, HttpStatus.SC_OK, true, returnValues); + + /** GET /config **/ + restClient.rest(HttpMethod.GET, "/config", null, HttpStatus.SC_OK, true, + "{'version':'STR','openviduPublicurl':'STR','openviduCdr':false,'maxRecvBandwidth':0,'minRecvBandwidth':0,'maxSendBandwidth':0,'minSendBandwidth':0,'openviduRecording':false," + + "'openviduRecordingVersion':'STR','openviduRecordingPath':'STR','openviduRecordingPublicAccess':false,'openviduRecordingNotification':'STR','openviduRecordingCustomLayout':'STR'}"); } private void listEmptyRecordings() { @@ -2120,7 +2298,7 @@ public class OpenViduTestAppE2eTest { Assert.assertEquals( "Resolution (" + recording.getResolution() + ") of recording entity is not equal to real video resolution (" + realResolution + ")", - realResolution, recording.getResolution()); + recording.getResolution(), realResolution); log.info("Recording map color: {}", colorMap.toString()); isFine = this.checkVideoAverageRgbGreen(colorMap); @@ -2137,8 +2315,8 @@ public class OpenViduTestAppE2eTest { // Should be only 2 files: zip and metadata File folder = new File(recPath); Assert.assertEquals( - "There are more than 2 files (ZIP and metadata) inside individual recording folder " + recPath, - folder.listFiles().length, 2); + "There are more than 2 files (ZIP and metadata) inside individual recording folder " + recPath, 2, + folder.listFiles().length); File file1 = new File(recPath + recording.getName() + ".zip"); File file2 = new File(recPath + ".recording." + recording.getId()); diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/CustomHttpClient.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/CustomHttpClient.java index cbc31681..637aef84 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/CustomHttpClient.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/CustomHttpClient.java @@ -37,7 +37,6 @@ import org.apache.http.ssl.SSLContextBuilder; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.json.simple.parser.JSONParser; import org.junit.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,8 +56,6 @@ public class CustomHttpClient { private String openviduUrl; private String headerAuth; - private JSONParser parser = new JSONParser(); - public CustomHttpClient(String openviduUrl, String openviduSecret) { this.openviduUrl = openviduUrl.replaceFirst("/*$", ""); this.headerAuth = "Basic " + Base64.getEncoder().encodeToString(("OPENVIDUAPP:" + openviduSecret).getBytes()); @@ -89,39 +86,40 @@ public class CustomHttpClient { } } - public void rest(HttpMethod method, String path, int status) { - this.commonRest(method, path, null, status); + public JSONObject rest(HttpMethod method, String path, int status) { + return this.commonRest(method, path, null, status); } - public void rest(HttpMethod method, String path, String body, int status) { - this.commonRest(method, path, body, status); + public JSONObject rest(HttpMethod method, String path, String body, int status) { + return this.commonRest(method, path, body, status); } - public void rest(HttpMethod method, String path, String body, int status, boolean exactFields, - String jsonElmentString) { + public JSONObject rest(HttpMethod method, String path, String body, int status, boolean exactReturnedFields, + String jsonReturnedValue) { JSONObject json = this.commonRest(method, path, body, status); JSONObject jsonObjExpected = null; - jsonElmentString.replaceAll("'", "\""); + jsonReturnedValue.replaceAll("'", "\""); try { - jsonObjExpected = new JSONObject((String) jsonElmentString); + jsonObjExpected = new JSONObject((String) jsonReturnedValue); } catch (JSONException e1) { - Assert.fail("Expected json element is a string without a JSON format: " + jsonElmentString); + Assert.fail("Expected json element is a string without a JSON format: " + jsonReturnedValue); } - if (exactFields) { + if (exactReturnedFields) { Assert.assertEquals("Error in number of keys in JSON response to POST " + path, jsonObjExpected.length(), json.length()); } for (String key : jsonObjExpected.keySet()) { json.get(key); } + return json; } - public void rest(HttpMethod method, String path, String body, int status, boolean exactFields, + public JSONObject rest(HttpMethod method, String path, String body, int status, boolean exactReturnedFields, Map jsonResponse) { org.json.JSONObject json = this.commonRest(method, path, body, status); - if (exactFields) { + if (exactReturnedFields) { Assert.assertEquals("Error in number of keys in JSON response to POST " + path, jsonResponse.size(), json.length()); } @@ -166,6 +164,7 @@ public class CustomHttpClient { Assert.fail("JSON response field cannot be parsed: " + entry.toString()); } } + return json; } private org.json.JSONObject commonRest(HttpMethod method, String path, String body, int status) {