Skip to content

Commit

Permalink
openvidu-server: COMPOSED_QUICK_START fixes when stopping and launchi…
Browse files Browse the repository at this point in the history
…ng container
  • Loading branch information
pabloFuente committed Jul 2, 2020
1 parent b921bac commit 2dada07
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import io.openvidu.java.client.Recording;
import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.jsonrpc.message.Request;
import org.slf4j.Logger;
Expand All @@ -48,6 +47,7 @@
import io.openvidu.client.OpenViduException.Code;
import io.openvidu.client.internal.ProtocolElements;
import io.openvidu.java.client.OpenViduRole;
import io.openvidu.java.client.Recording;
import io.openvidu.java.client.SessionProperties;
import io.openvidu.server.cdr.CDREventRecording;
import io.openvidu.server.config.OpenviduConfig;
Expand Down Expand Up @@ -543,21 +543,20 @@ public void closeSession(String sessionId, EndReason reason) {

public void closeSessionAndEmptyCollections(Session session, EndReason reason, boolean stopRecording) {

if (openviduConfig.isRecordingModuleEnabled() && stopRecording
&& this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) {
try {
recordingManager.stopRecording(session, null, RecordingManager.finalReason(reason), true);
} catch (OpenViduException e) {
log.error("Error stopping recording of session {}: {}", session.getSessionId(), e.getMessage());
if (openviduConfig.isRecordingModuleEnabled()) {
if (stopRecording && this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) {
try {
recordingManager.stopRecording(session, null, RecordingManager.finalReason(reason));
} catch (OpenViduException e) {
log.error("Error stopping recording of session {}: {}", session.getSessionId(), e.getMessage());
}
}
} else if(openviduConfig.isRecordingModuleEnabled() && stopRecording
&& !this.recordingManager.sessionIsBeingRecorded(session.getSessionId())
&& session.getSessionProperties().defaultOutputMode().equals(Recording.OutputMode.COMPOSED_QUICK_START)
&& this.recordingManager.getStartedRecording(session.getSessionId()) != null) {
try {
this.recordingManager.stopComposedQuickStartContainer(session, reason);
} catch (OpenViduException e) {
log.error("Error stopping COMPOSED_QUICK_START container of session {}", session.getSessionId());
if (Recording.OutputMode.COMPOSED_QUICK_START.equals(session.getSessionProperties().defaultOutputMode())) {
try {
this.recordingManager.stopComposedQuickStartContainer(session, reason);
} catch (OpenViduException e) {
log.error("Error stopping COMPOSED_QUICK_START container of session {}", session.getSessionId());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected Recording startRecordingWithVideo(Session session, Recording recording
}

@Override
protected Recording stopRecordingWithVideo(Session session, Recording recording, EndReason reason, boolean hasSessionEnded) {
protected Recording stopRecordingWithVideo(Session session, Recording recording, EndReason reason) {
log.info("Stopping COMPOSED_QUICK_START ({}) recording {} of session {}. Reason: {}",
recording.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId(),
RecordingManager.finalReason(reason));
Expand All @@ -106,31 +106,12 @@ protected Recording stopRecordingWithVideo(Session session, Recording recording,
recording.getId());
}

if (hasSessionEnded) {
// Gracefully stop ffmpeg process
try {
dockerManager.runCommandInContainer(containerId, "./composed_quick_start.sh --stop-recording", 10);
} catch (InterruptedException e1) {
e1.printStackTrace();
}

try {
dockerManager.removeDockerContainer(containerId, true);
} catch (Exception e) {
failRecordingCompletion(recording, containerId, new OpenViduException(OpenViduException.Code.RECORDING_COMPLETION_ERROR_CODE,
"Can't remove COMPOSED_QUICK_START recording container from session" + session.getSessionId()));
}

containers.remove(containerId);
sessionsContainers.remove(recording.getSessionId());
} else {
try {
dockerManager.runCommandInContainer(containerId, "./composed_quick_start.sh --stop-recording", 10);
} catch (InterruptedException e1) {
cleanRecordingMaps(recording);
log.error("Error stopping recording for session id: {}", session.getSessionId());
e1.printStackTrace();
}
try {
dockerManager.runCommandInContainer(containerId, "./composed_quick_start.sh --stop-recording", 10);
} catch (InterruptedException e1) {
cleanRecordingMaps(recording);
log.error("Error stopping recording for session id: {}", session.getSessionId());
e1.printStackTrace();
}

recording = updateRecordingAttributes(recording);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,18 @@ public Recording startRecording(Session session, RecordingProperties properties)
}

@Override
public Recording stopRecording(Session session, Recording recording, EndReason reason, boolean hasSessionEnded) {
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
recording = this.sealRecordingMetadataFileAsStopped(recording);
if (recording.hasVideo()) {
return this.stopRecordingWithVideo(session, recording, reason, hasSessionEnded);
return this.stopRecordingWithVideo(session, recording, reason);
} else {
return this.stopRecordingAudioOnly(session, recording, reason, 0);
}
}

public Recording stopRecording(Session session, Recording recording, EndReason reason, long kmsDisconnectionTime, boolean hasSessionEnded) {
public Recording stopRecording(Session session, Recording recording, EndReason reason, long kmsDisconnectionTime) {
if (recording.hasVideo()) {
return this.stopRecordingWithVideo(session, recording, reason, hasSessionEnded);
return this.stopRecordingWithVideo(session, recording, reason);
} else {
return this.stopRecordingAudioOnly(session, recording, reason, kmsDisconnectionTime);
}
Expand Down Expand Up @@ -228,7 +228,7 @@ private Recording startRecordingAudioOnly(Session session, Recording recording,
return recording;
}

protected Recording stopRecordingWithVideo(Session session, Recording recording, EndReason reason, boolean hasSessionEnded) {
protected Recording stopRecordingWithVideo(Session session, Recording recording, EndReason reason) {

log.info("Stopping composed ({}) recording {} of session {}. Reason: {}",
recording.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ public Recording startRecording(Session session, RecordingProperties properties)
}
}

public Recording stopRecording(Session session, String recordingId, EndReason reason, boolean hasSessionEnded) {
public Recording stopRecording(Session session, String recordingId, EndReason reason) {
Recording recording;
if (session == null) {
recording = this.startedRecordings.get(recordingId);
Expand All @@ -316,14 +316,13 @@ public Recording stopRecording(Session session, String recordingId, EndReason re

switch (recording.getOutputMode()) {
case COMPOSED:
recording = this.composedRecordingService.stopRecording(session, recording, reason, hasSessionEnded);
recording = this.composedRecordingService.stopRecording(session, recording, reason);
break;
case COMPOSED_QUICK_START:
recording = this.composedQuickStartRecordingService.stopRecording(session, recording, reason,
hasSessionEnded);
recording = this.composedQuickStartRecordingService.stopRecording(session, recording, reason);
break;
case INDIVIDUAL:
recording = this.singleStreamRecordingService.stopRecording(session, recording, reason, hasSessionEnded);
recording = this.singleStreamRecordingService.stopRecording(session, recording, reason);
break;
}
this.abortAutomaticRecordingStopThread(session, reason);
Expand All @@ -335,8 +334,7 @@ public Recording forceStopRecording(Session session, EndReason reason, long kmsD
recording = this.sessionsRecordings.get(session.getSessionId());
switch (recording.getOutputMode()) {
case COMPOSED:
recording = this.composedRecordingService.stopRecording(session, recording, reason, kmsDisconnectionTime,
true);
recording = this.composedRecordingService.stopRecording(session, recording, reason, kmsDisconnectionTime);
if (recording.hasVideo()) {
// Evict the recorder participant if composed recording with video
this.sessionManager.evictParticipant(
Expand All @@ -346,7 +344,7 @@ public Recording forceStopRecording(Session session, EndReason reason, long kmsD
break;
case COMPOSED_QUICK_START:
recording = this.composedQuickStartRecordingService.stopRecording(session, recording, reason,
kmsDisconnectionTime, true);
kmsDisconnectionTime);
if (recording.hasVideo()) {
// Evict the recorder participant if composed recording with video
this.sessionManager.evictParticipant(
Expand Down Expand Up @@ -557,7 +555,7 @@ public void initAutomaticRecordingStopThread(final Session session) {
log.info(
"Automatic stopping recording {}. There are users connected to session {}, but no one is publishing",
recordingId, session.getSessionId());
this.stopRecording(session, recordingId, EndReason.automaticStop, true);
this.stopRecording(session, recordingId, EndReason.automaticStop);
}
} finally {
if (!alreadyUnlocked) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public abstract class RecordingService {

public abstract Recording startRecording(Session session, RecordingProperties properties) throws OpenViduException;

public abstract Recording stopRecording(Session session, Recording recording, EndReason reason,
boolean hasSessionEnded);
public abstract Recording stopRecording(Session session, Recording recording, EndReason reason);

/**
* Generates metadata recording file (".recording.RECORDING_ID" JSON file to
Expand Down Expand Up @@ -178,7 +177,7 @@ protected OpenViduException failStartRecording(Session session, Recording record
recording.setStatus(io.openvidu.java.client.Recording.Status.failed);
this.recordingManager.startingRecordings.remove(recording.getId());
this.recordingManager.sessionsRecordingsStarting.remove(session.getSessionId());
this.stopRecording(session, recording, null, true);
this.stopRecording(session, recording, null);
return new OpenViduException(Code.RECORDING_START_ERROR_CODE, errorMessage);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public Recording startRecording(Session session, RecordingProperties properties)
}

@Override
public Recording stopRecording(Session session, Recording recording, EndReason reason, boolean hasSessionEnded) {
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
recording = this.sealRecordingMetadataFileAsStopped(recording);
return this.stopRecording(session, recording, reason, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ public ResponseEntity<?> stopRecordingSession(@PathVariable("recordingId") Strin
Session session = sessionManager.getSession(recording.getSessionId());

Recording stoppedRecording = this.recordingManager.stopRecording(session, recording.getId(),
EndReason.recordingStoppedByServer, false);
EndReason.recordingStoppedByServer);

session.recordingManuallyStopped.set(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public class OpenViduTestAppE2eTest {

private static final Logger log = LoggerFactory.getLogger(OpenViduTestAppE2eTest.class);
private static final CommandLineExecutor commandLine = new CommandLineExecutor();
private static final String RECORDING_IMAGE = "openvidu/openvidu-recording";

MyUser user;
Collection<MyUser> otherUsers = new ArrayList<>();
Expand Down Expand Up @@ -255,6 +256,7 @@ void dispose() {
}
});
if (isRecordingTest) {
removeAllRecordingContiners();
try {
FileUtils.cleanDirectory(new File("/opt/openvidu/recordings"));
} catch (IOException e) {
Expand Down Expand Up @@ -1233,6 +1235,70 @@ void remoteComposedRecordTest() throws Exception {
gracefullyLeaveParticipants(1);
}

@Test
@DisplayName("Remote composed quick start record")
void remoteComposedQuickStartRecordTest() throws Exception {
isRecordingTest = true;

setupBrowser("chrome");

log.info("Remote composed quick start record");

final String sessionName = "COMPOSED_QUICK_START_RECORDED_SESSION";

user.getDriver().findElement(By.id("add-user-btn")).click();
user.getDriver().findElement(By.id("session-name-input-0")).clear();
user.getDriver().findElement(By.id("session-name-input-0")).sendKeys(sessionName);

user.getDriver().findElement(By.id("session-settings-btn-0")).click();
Thread.sleep(1000);
user.getDriver().findElement(By.id("output-mode-select")).click();
Thread.sleep(500);
user.getDriver().findElement(By.id("option-COMPOSED_QUICK_START")).click();
Thread.sleep(500);
user.getDriver().findElement(By.id("save-btn")).click();
Thread.sleep(1000);

// Join the subscriber user to the session
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .publish-checkbox")).click();
user.getDriver().findElement(By.className("join-btn")).click();
user.getEventManager().waitUntilEventReaches("connectionCreated", 1);

// Check the recording container is up and running but no ongoing recordings
checkDockerContainerRunning(RECORDING_IMAGE, 1);
Assert.assertEquals("Wrong number of recordings found", 0, OV.listRecordings().size());

// Join the publisher user to the session
user.getDriver().findElement(By.id("add-user-btn")).click();
user.getDriver().findElement(By.id("session-name-input-1")).clear();
user.getDriver().findElement(By.id("session-name-input-1")).sendKeys(sessionName);
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .join-btn")).click();

user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
user.getEventManager().waitUntilEventReaches("accessAllowed", 1);
user.getEventManager().waitUntilEventReaches("streamCreated", 2);
user.getEventManager().waitUntilEventReaches("streamPlaying", 2);

// Start recording
OV.fetch();
String recId = OV.startRecording(sessionName).getId();
user.getEventManager().waitUntilEventReaches("recordingStarted", 2);
checkDockerContainerRunning("openvidu/openvidu-recording", 1);

Thread.sleep(1000);

Assert.assertEquals("Wrong number of recordings found", 1, OV.listRecordings().size());
OV.stopRecording(recId);
user.getEventManager().waitUntilEventReaches("recordingStopped", 2);
checkDockerContainerRunning("openvidu/openvidu-recording", 1);

Assert.assertEquals("Wrong number of sessions", 1, OV.getActiveSessions().size());
Session session = OV.getActiveSessions().get(0);
session.close();

checkDockerContainerRunning("openvidu/openvidu-recording", 0);
}

@Test
@DisplayName("Remote individual record")
void remoteIndividualRecordTest() throws Exception {
Expand Down Expand Up @@ -2928,7 +2994,7 @@ void webhookTest() throws Exception {
Assert.assertEquals("Wrong number of properties in event 'recordingStatusChanged'", 12 + 1,
event.keySet().size());
Assert.assertEquals("Wrong recording status in webhook event", "ready", event.get("status").getAsString());
Assert.assertTrue("Wrong recording outputMode in webhook event", event.get("size").getAsLong() > 0);
Assert.assertTrue("Wrong recording size in webhook event", event.get("size").getAsLong() > 0);
Assert.assertTrue("Wrong recording outputMode in webhook event", event.get("duration").getAsLong() > 0);
Assert.assertEquals("Wrong recording reason in webhook event", "sessionClosedByServer",
event.get("reason").getAsString());
Expand Down Expand Up @@ -3463,4 +3529,14 @@ private void restartKms() {
this.startKms();
}

private void checkDockerContainerRunning(String imageName, int amount) {
int number = Integer.parseInt(commandLine.executeCommand("docker ps | grep " + imageName + " | wc -l"));
Assert.assertEquals("Wrong number of Docker containers for image " + imageName + " running", amount, number);
}

private void removeAllRecordingContiners() {
commandLine.executeCommand("docker ps -a | awk '{ print $1,$2 }' | grep " + RECORDING_IMAGE
+ " | awk '{print $1 }' | xargs -I {} docker rm -f {}");
}

}

0 comments on commit 2dada07

Please sign in to comment.