mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: CommandExecutor timeout
parent
c150b87a2a
commit
c4a6ca5543
|
@ -295,7 +295,7 @@ public abstract class SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String newToken(Session session, OpenViduRole role, String serverMetadata,
|
public String newToken(Session session, OpenViduRole role, String serverMetadata,
|
||||||
KurentoTokenOptions kurentoTokenOptions) throws OpenViduException {
|
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
||||||
if (!formatChecker.isServerMetadataFormatCorrect(serverMetadata)) {
|
if (!formatChecker.isServerMetadataFormatCorrect(serverMetadata)) {
|
||||||
log.error("Data invalid format");
|
log.error("Data invalid format");
|
||||||
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format");
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format");
|
||||||
|
@ -307,7 +307,7 @@ public abstract class SessionManager {
|
||||||
return tokenObj.getToken();
|
return tokenObj.getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Token newTokenForInsecureUser(Session session, String token, String serverMetadata) {
|
public Token newTokenForInsecureUser(Session session, String token, String serverMetadata) throws Exception {
|
||||||
Token tokenObj = new Token(token, OpenViduRole.PUBLISHER, serverMetadata != null ? serverMetadata : "",
|
Token tokenObj = new Token(token, OpenViduRole.PUBLISHER, serverMetadata != null ? serverMetadata : "",
|
||||||
this.openviduConfig.isTurnadminAvailable() ? this.coturnCredentialsService.createUser() : null, null);
|
this.openviduConfig.isTurnadminAvailable() ? this.coturnCredentialsService.createUser() : null, null);
|
||||||
session.storeToken(tokenObj);
|
session.storeToken(tokenObj);
|
||||||
|
|
|
@ -23,6 +23,6 @@ import io.openvidu.server.kurento.core.KurentoTokenOptions;
|
||||||
public interface TokenGenerator {
|
public interface TokenGenerator {
|
||||||
|
|
||||||
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
||||||
KurentoTokenOptions kurentoTokenOptions);
|
KurentoTokenOptions kurentoTokenOptions) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class TokenGeneratorDefault implements TokenGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
||||||
KurentoTokenOptions kurentoTokenOptions) {
|
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
||||||
String token = OpenViduServer.wsUrl;
|
String token = OpenViduServer.wsUrl;
|
||||||
token += "?sessionId=" + sessionId;
|
token += "?sessionId=" + sessionId;
|
||||||
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
||||||
|
|
|
@ -74,13 +74,12 @@ public class BashCoturnCredentialsService extends CoturnCredentialsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TurnCredentials createUser() {
|
public TurnCredentials createUser() throws IOException, InterruptedException {
|
||||||
TurnCredentials credentials = null;
|
TurnCredentials credentials = null;
|
||||||
log.info("Creating COTURN user");
|
log.info("Creating COTURN user");
|
||||||
String user = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
|
String user = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
|
||||||
String pass = RandomStringUtils.randomAlphanumeric(6).toLowerCase();
|
String pass = RandomStringUtils.randomAlphanumeric(6).toLowerCase();
|
||||||
String command = "turnadmin -a -u " + user + " -r openvidu -p " + pass + " -N " + this.coturnDatabaseString;
|
String command = "turnadmin -a -u " + user + " -r openvidu -p " + pass + " -N " + this.coturnDatabaseString;
|
||||||
try {
|
|
||||||
String response = CommandExecutor.execCommand("/bin/sh", "-c", command);
|
String response = CommandExecutor.execCommand("/bin/sh", "-c", command);
|
||||||
if (response.contains("connection success: " + this.trimmedCoturnDatabaseString)) {
|
if (response.contains("connection success: " + this.trimmedCoturnDatabaseString)) {
|
||||||
credentials = new TurnCredentials(user, pass);
|
credentials = new TurnCredentials(user, pass);
|
||||||
|
@ -89,9 +88,6 @@ public class BashCoturnCredentialsService extends CoturnCredentialsService {
|
||||||
} else {
|
} else {
|
||||||
log.info("COTURN user created: false");
|
log.info("COTURN user created: false");
|
||||||
}
|
}
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return credentials;
|
return credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public abstract class CoturnCredentialsService {
|
||||||
protected String coturnDatabaseString;
|
protected String coturnDatabaseString;
|
||||||
protected String trimmedCoturnDatabaseString;
|
protected String trimmedCoturnDatabaseString;
|
||||||
|
|
||||||
public abstract TurnCredentials createUser();
|
public abstract TurnCredentials createUser() throws Exception;
|
||||||
|
|
||||||
public abstract boolean deleteUser(String user);
|
public abstract boolean deleteUser(String user);
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ public class SessionRestController {
|
||||||
public ResponseEntity<?> listSessions(
|
public ResponseEntity<?> listSessions(
|
||||||
@RequestParam(value = "webRtcStats", defaultValue = "false", required = false) boolean webRtcStats) {
|
@RequestParam(value = "webRtcStats", defaultValue = "false", required = false) boolean webRtcStats) {
|
||||||
|
|
||||||
log.info("REST API: GET /api/sessions");
|
log.info("REST API: GET /api/sessions?webRtcStats={}", webRtcStats);
|
||||||
|
|
||||||
Collection<Session> sessions = this.sessionManager.getSessionsWithNotActive();
|
Collection<Session> sessions = this.sessionManager.getSessionsWithNotActive();
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
|
@ -423,6 +423,10 @@ public class SessionRestController {
|
||||||
responseJson.add("kurentoOptions", kurentoOptsResponse);
|
responseJson.add("kurentoOptions", kurentoOptsResponse);
|
||||||
}
|
}
|
||||||
return new ResponseEntity<>(responseJson.toString(), getResponseHeaders(), HttpStatus.OK);
|
return new ResponseEntity<>(responseJson.toString(), getResponseHeaders(), HttpStatus.OK);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return this.generateErrorResponse(
|
||||||
|
"Error generating token for session " + sessionId + ": " + e.getMessage(), "/api/tokens",
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
} finally {
|
} finally {
|
||||||
session.closingLock.readLock().unlock();
|
session.closingLock.readLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,12 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
sessionManager.newInsecureParticipant(participantPrivatetId);
|
sessionManager.newInsecureParticipant(participantPrivatetId);
|
||||||
token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
||||||
+ RandomStringUtils.randomAlphanumeric(15);
|
+ RandomStringUtils.randomAlphanumeric(15);
|
||||||
|
try {
|
||||||
sessionManager.newTokenForInsecureUser(session, token, null);
|
sessionManager.newTokenForInsecureUser(session, token, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE,
|
||||||
|
"Unable to create token for session " + sessionId + ": " + e.getMessage());
|
||||||
|
}
|
||||||
if (recorder) {
|
if (recorder) {
|
||||||
generateRecorderParticipant = true;
|
generateRecorderParticipant = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,21 @@ import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pablo Fuente (pablofuenteperez@gmail.com)
|
* @author Pablo Fuente (pablofuenteperez@gmail.com)
|
||||||
*/
|
*/
|
||||||
public class CommandExecutor {
|
public class CommandExecutor {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CommandExecutor.class);
|
||||||
|
|
||||||
|
private static final long MILLIS_TIMEOUT = 10000;
|
||||||
|
|
||||||
public static String execCommand(String... command) throws IOException, InterruptedException {
|
public static String execCommand(String... command) throws IOException, InterruptedException {
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
processBuilder.redirectErrorStream(true);
|
processBuilder.redirectErrorStream(true);
|
||||||
|
@ -44,7 +53,12 @@ public class CommandExecutor {
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command).redirectOutput(standardOutputFile)
|
ProcessBuilder processBuilder = new ProcessBuilder(command).redirectOutput(standardOutputFile)
|
||||||
.redirectError(errorOutputFile);
|
.redirectError(errorOutputFile);
|
||||||
Process process = processBuilder.start();
|
Process process = processBuilder.start();
|
||||||
process.waitFor();
|
if (!process.waitFor(MILLIS_TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||||
|
log.error("Command {} did not receive a response in {} ms", Arrays.toString(command), MILLIS_TIMEOUT);
|
||||||
|
String errorMsg = "Current process status of host:\n" + gatherLinuxHostInformation();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new IOException(errorMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String commonExecCommand(ProcessBuilder processBuilder) throws IOException, InterruptedException {
|
private static String commonExecCommand(ProcessBuilder processBuilder) throws IOException, InterruptedException {
|
||||||
|
@ -60,7 +74,14 @@ public class CommandExecutor {
|
||||||
while ((readLine = processOutputReader.readLine()) != null) {
|
while ((readLine = processOutputReader.readLine()) != null) {
|
||||||
processOutput.append(readLine + System.lineSeparator());
|
processOutput.append(readLine + System.lineSeparator());
|
||||||
}
|
}
|
||||||
process.waitFor();
|
|
||||||
|
if (!process.waitFor(MILLIS_TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||||
|
log.error("Command {} did not receive a response in {} ms",
|
||||||
|
Arrays.toString(processBuilder.command().toArray()), MILLIS_TIMEOUT);
|
||||||
|
String errorMsg = "Current process status of host:\n" + gatherLinuxHostInformation();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new IOException(errorMsg);
|
||||||
|
}
|
||||||
output = processOutput.toString().trim();
|
output = processOutput.toString().trim();
|
||||||
} finally {
|
} finally {
|
||||||
if (inputStreamReader != null) {
|
if (inputStreamReader != null) {
|
||||||
|
@ -73,4 +94,9 @@ public class CommandExecutor {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String gatherLinuxHostInformation() throws IOException, InterruptedException {
|
||||||
|
final String psCommand = "ps -eo pid,ppid,user,%mem,%cpu,cmd --sort=-%cpu";
|
||||||
|
return execCommand("/bin/sh", "-c", psCommand);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue