openvidu-server: OPENVIDU_PUBLICURL to DOMAIN_OR_PUBLIC_IP and HTTPS_PORT

pull/457/head
pabloFuente 2020-04-30 21:47:24 +02:00
parent cd2f472034
commit aa914ca5d6
12 changed files with 107 additions and 126 deletions

View File

@ -9,5 +9,5 @@ command=/bin/bash /kms.sh
redirect_stderr=true redirect_stderr=true
[program:openvidu-server] [program:openvidu-server]
command=/bin/bash -c "java -jar -Dspring.profiles.active=docker /openvidu-server.jar" command=/bin/bash -c "java -jar -Dspring.config.additional-location=classpath:/application-container.properties /openvidu-server.jar"
redirect_stderr=true redirect_stderr=true

View File

@ -86,7 +86,6 @@ public class OpenViduServer implements JsonRpcConfigurer {
private static final Logger log = LoggerFactory.getLogger(OpenViduServer.class); private static final Logger log = LoggerFactory.getLogger(OpenViduServer.class);
public static final String WS_PATH = "/openvidu"; public static final String WS_PATH = "/openvidu";
public static String publicurlType;
public static String wsUrl; public static String wsUrl;
public static String httpUrl; public static String httpUrl;
@ -221,7 +220,32 @@ public class OpenViduServer implements JsonRpcConfigurer {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
checkConfigProperties(OpenviduConfig.class); Map<String, String> CONFIG_PROPS = checkConfigProperties(OpenviduConfig.class);
if (CONFIG_PROPS.get("SERVER_PORT") != null) {
// Configuration property SERVER_PORT has been explicitly defined.
// Must initialize the application in that port on the host regardless of what
// HTTPS_PORT says. HTTPS_PORT does get used in the public URL.
System.setProperty("server.port", CONFIG_PROPS.get("SERVER_PORT"));
log.warn(
"You have set property server.port (or SERVER_PORT). This will serve OpenVidu Server on your host at port "
+ CONFIG_PROPS.get("SERVER_PORT") + ". But property HTTPS_PORT ("
+ CONFIG_PROPS.get("HTTPS_PORT")
+ ") still configures the port that should be used to connect to OpenVidu Server from outside. "
+ "Bear this in mind when configuring a proxy in front of OpenVidu Server");
} else if (CONFIG_PROPS.get("HTTPS_PORT") != null) {
// Configuration property SERVER_PORT has NOT been explicitly defined.
// Must initialize the application in port HTTPS_PORT on the host. HTTPS_PORT
// does get used in the public URL as well.
System.setProperty("server.port", CONFIG_PROPS.get("HTTPS_PORT"));
}
log.info("Using /dev/urandom for secure random generation"); log.info("Using /dev/urandom for secure random generation");
System.setProperty("java.security.egd", "file:/dev/./urandom"); System.setProperty("java.security.egd", "file:/dev/./urandom");
@ -229,7 +253,7 @@ public class OpenViduServer implements JsonRpcConfigurer {
} }
public static <T> void checkConfigProperties(Class<T> configClass) throws InterruptedException { public static <T> Map<String, String> checkConfigProperties(Class<T> configClass) throws InterruptedException {
ConfigurableApplicationContext app = SpringApplication.run(configClass, ConfigurableApplicationContext app = SpringApplication.run(configClass,
new String[] { "--spring.main.web-application-type=none" }); new String[] { "--spring.main.web-application-type=none" });
@ -270,18 +294,21 @@ public class OpenViduServer implements JsonRpcConfigurer {
String msg = "\n\n\n" + " Configuration properties\n" + " ------------------------\n" + "\n"; String msg = "\n\n\n" + " Configuration properties\n" + " ------------------------\n" + "\n";
Map<String, String> configProps = config.getConfigProps(); final Map<String, String> CONFIG_PROPS = config.getConfigProps();
List<String> configPropNames = new ArrayList<>(config.getUserProperties()); List<String> configPropNames = new ArrayList<>(config.getUserProperties());
Collections.sort(configPropNames); Collections.sort(configPropNames);
for (String property : configPropNames) { for (String property : configPropNames) {
String value = configProps.get(property); String value = CONFIG_PROPS.get(property);
msg += " * " + config.getPropertyName(property) + "=" + (value == null ? "" : value) + "\n"; msg += " * " + config.getPropertyName(property) + "=" + (value == null ? "" : value) + "\n";
} }
msg += "\n\n"; msg += "\n\n";
log.info(msg); log.info(msg);
return CONFIG_PROPS;
} }
return null;
} }
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)

View File

@ -95,8 +95,6 @@ public class OpenviduConfig {
private static final boolean SHOW_PROPERTIES_AS_ENV_VARS = true; private static final boolean SHOW_PROPERTIES_AS_ENV_VARS = true;
public static final List<String> OPENVIDU_VALID_PUBLICURL_VALUES = Arrays.asList("local", "docker");
private List<Error> configErrors = new ArrayList<>(); private List<Error> configErrors = new ArrayList<>();
private Map<String, String> configProps = new HashMap<>(); private Map<String, String> configProps = new HashMap<>();
@ -153,13 +151,15 @@ public class OpenviduConfig {
private List<String> kmsUrisList; private List<String> kmsUrisList;
private String openviduSecret; private String domainOrPublicIp;
private String openviduPublicUrl; private String openviduPublicUrl;
private String openviduRecordingComposedUrl; private Integer httpsPort;
private int serverPort; private String openviduSecret;
private String openviduRecordingComposedUrl;
private String coturnRedisDbname; private String coturnRedisDbname;
@ -183,10 +183,6 @@ public class OpenviduConfig {
// Plain config properties getters // Plain config properties getters
public int getServerPort() {
return this.serverPort;
}
public String getCoturnDatabaseDbname() { public String getCoturnDatabaseDbname() {
return this.coturnRedisDbname; return this.coturnRedisDbname;
} }
@ -195,10 +191,18 @@ public class OpenviduConfig {
return kmsUrisList; return kmsUrisList;
} }
public String getDomainOrPublicIp() {
return this.domainOrPublicIp;
}
public String getOpenViduPublicUrl() { public String getOpenViduPublicUrl() {
return this.openviduPublicUrl; return this.openviduPublicUrl;
} }
public Integer getHttpsPort() {
return this.httpsPort;
}
public String getOpenViduSecret() { public String getOpenViduSecret() {
return this.openviduSecret; return this.openviduSecret;
} }
@ -441,7 +445,7 @@ public class OpenviduConfig {
} }
protected List<String> getNonUserProperties() { protected List<String> getNonUserProperties() {
return Arrays.asList("server.port", "SERVER_PORT", "DOTENV_PATH", "COTURN_IP", "COTURN_REDIS_IP", "KMS_URIS", return Arrays.asList("server.port", "SERVER_PORT", "DOTENV_PATH", "COTURN_IP", "COTURN_REDIS_IP",
"COTURN_REDIS_DBNAME", "COTURN_REDIS_PASSWORD", "COTURN_REDIS_CONNECT_TIMEOUT"); "COTURN_REDIS_DBNAME", "COTURN_REDIS_PASSWORD", "COTURN_REDIS_CONNECT_TIMEOUT");
} }
@ -455,7 +459,8 @@ public class OpenviduConfig {
} }
checkHttpsPort(); checkHttpsPort();
checkOpenviduPublicurl(); checkDomainOrPublicIp();
populateSpringServerPort();
coturnRedisDbname = getValue("COTURN_REDIS_DBNAME"); coturnRedisDbname = getValue("COTURN_REDIS_DBNAME");
@ -545,34 +550,19 @@ public class OpenviduConfig {
} }
} }
private void checkOpenviduPublicurl() { private void checkDomainOrPublicIp() {
final String property = "OPENVIDU_DOMAIN_OR_PUBLIC_IP"; final String property = "DOMAIN_OR_PUBLIC_IP";
String domain = getValue(property); String domain = asOptionalInetAddress(property);
if (domain != null && !domain.isEmpty()) { if (domain != null && !domain.isEmpty()) {
this.domainOrPublicIp = domain;
this.openviduPublicUrl = "https://" + domain; this.openviduPublicUrl = "https://" + domain;
if (this.serverPort != 443) { if (this.httpsPort != 443) {
this.openviduPublicUrl += (":" + this.serverPort); this.openviduPublicUrl += (":" + this.httpsPort);
} }
} else {
final String urlProperty = "OPENVIDU_PUBLICURL";
String publicurl = getValue(urlProperty);
if (publicurl == null || publicurl.isEmpty()) {
addError(property, "Cannot be empty");
} else {
if (!OPENVIDU_VALID_PUBLICURL_VALUES.contains(publicurl)) {
try {
checkUrl(publicurl);
} catch (Exception e) {
addError(property, "Is not a valid URL. " + e.getMessage());
}
}
this.openviduPublicUrl = publicurl;
}
}
if (openviduPublicUrl != null && !openviduPublicUrl.isEmpty()) {
calculatePublicUrl(); calculatePublicUrl();
} else {
addError(property, "Cannot be empty");
} }
} }
@ -580,17 +570,7 @@ public class OpenviduConfig {
String property = "HTTPS_PORT"; String property = "HTTPS_PORT";
String httpsPort = getValue(property); String httpsPort = getValue(property);
if (httpsPort == null) { if (httpsPort == null) {
// This should only occur on dev container addError(property, "Cannot be undefined");
property = "SERVER_PORT";
httpsPort = getValue(property);
if (httpsPort == null) {
property = "server.port";
httpsPort = getValue(property, false);
if (httpsPort == null || httpsPort.isEmpty()) {
addError(property, "Cannot be undefined");
return;
}
}
} }
int httpsPortNumber = 0; int httpsPortNumber = 0;
try { try {
@ -599,55 +579,43 @@ public class OpenviduConfig {
addError(property, "Is not a valid port. Must be an integer. " + e.getMessage()); addError(property, "Is not a valid port. Must be an integer. " + e.getMessage());
return; return;
} }
if (httpsPortNumber > 0 && httpsPortNumber <= 65535) { if (httpsPortNumber > 0 && httpsPortNumber <= 65535) {
serverPort = httpsPortNumber; this.httpsPort = httpsPortNumber;
} else { } else {
addError(property, "Is not a valid port. Valid port range exceeded with value " + httpsPortNumber); addError(property, "Is not a valid port. Valid port range exceeded with value " + httpsPortNumber);
return; return;
} }
} }
private void calculatePublicUrl() { /**
String publicUrl = this.getOpenViduPublicUrl(); * Will add to collection of configuration properties the property "SERVER_PORT"
* only if property "SERVER_PORT" or "server.port" was explicitly defined. This
String type = ""; * doesn't mean this property won't have a default value if not explicitly
switch (publicUrl) { * defined (8080 is the default value given by Spring)
case "docker": */
try { private void populateSpringServerPort() {
String containerIp = OpenViduServer.getContainerIp(); String springServerPort = getValue("server.port", false);
OpenViduServer.wsUrl = "wss://" + containerIp + ":" + this.getServerPort(); if (springServerPort == null) {
} catch (Exception e) { springServerPort = getValue("SERVER_PORT", false);
log.error("Docker container IP was configured, but there was an error obtaining IP: "
+ e.getClass().getName() + " " + e.getMessage());
log.error("Fallback to local URL");
OpenViduServer.wsUrl = null;
}
break;
case "local":
break;
case "":
break;
default:
if (publicUrl.startsWith("https://")) {
OpenViduServer.wsUrl = publicUrl.replace("https://", "wss://");
} else if (publicUrl.startsWith("http://")) {
OpenViduServer.wsUrl = publicUrl.replace("http://", "wss://");
}
} }
if (springServerPort != null) {
this.configProps.put("SERVER_PORT", springServerPort);
}
}
if (OpenViduServer.wsUrl == null) { private void calculatePublicUrl() {
type = "local"; final String publicUrl = this.getOpenViduPublicUrl();
OpenViduServer.wsUrl = "wss://localhost:" + this.getServerPort(); if (publicUrl.startsWith("https://")) {
OpenViduServer.wsUrl = publicUrl.replace("https://", "wss://");
} else if (publicUrl.startsWith("http://")) {
OpenViduServer.wsUrl = publicUrl.replace("http://", "wss://");
} }
if (OpenViduServer.wsUrl.endsWith("/")) { if (OpenViduServer.wsUrl.endsWith("/")) {
OpenViduServer.wsUrl = OpenViduServer.wsUrl.substring(0, OpenViduServer.wsUrl.length() - 1); OpenViduServer.wsUrl = OpenViduServer.wsUrl.substring(0, OpenViduServer.wsUrl.length() - 1);
} }
String finalUrl = OpenViduServer.wsUrl.replaceFirst("wss://", "https://").replaceFirst("ws://", "http://"); String finalUrl = OpenViduServer.wsUrl.replaceFirst("wss://", "https://").replaceFirst("ws://", "http://");
this.setFinalUrl(finalUrl); this.setFinalUrl(finalUrl);
OpenViduServer.httpUrl = this.getFinalUrl(); OpenViduServer.httpUrl = this.getFinalUrl();
OpenViduServer.publicurlType = type;
} }
public List<String> checkKmsUris() { public List<String> checkKmsUris() {

View File

@ -103,6 +103,8 @@ public class ConfigRestController {
json.addProperty("VERSION", openviduBuildInfo.getVersion()); json.addProperty("VERSION", openviduBuildInfo.getVersion());
JsonArray kmsUris = new JsonArray(); JsonArray kmsUris = new JsonArray();
openviduConfig.getKmsUris().forEach(uri -> kmsUris.add(uri)); openviduConfig.getKmsUris().forEach(uri -> kmsUris.add(uri));
json.addProperty("DOMAIN_OR_PUBLIC_IP", openviduConfig.getDomainOrPublicIp());
json.addProperty("HTTPS_PORT", openviduConfig.getHttpsPort());
json.add("KMS_URIS", kmsUris); json.add("KMS_URIS", kmsUris);
json.addProperty("OPENVIDU_PUBLICURL", openviduConfig.getOpenViduPublicUrl()); json.addProperty("OPENVIDU_PUBLICURL", openviduConfig.getOpenViduPublicUrl());
json.addProperty("OPENVIDU_CDR", openviduConfig.isCdrEnabled()); json.addProperty("OPENVIDU_CDR", openviduConfig.isCdrEnabled());

View File

@ -3,7 +3,18 @@
{ {
"name": "DOTENV_PATH", "name": "DOTENV_PATH",
"type": "java.lang.String", "type": "java.lang.String",
"description": "Path to the .env configuration file" "description": "Path to the .env configuration file",
"defaultValue": "."
},
{
"name": "DOMAIN_OR_PUBLIC_IP",
"type": "java.lang.String",
"description": "Public domain or ip where OpenVidu Server will be accessible"
},
{
"name": "HTTPS_PORT",
"type": "java.lang.Integer",
"description": "Secure port where OpenVidu Server will listen"
}, },
{ {
"name": "KMS_URIS", "name": "KMS_URIS",
@ -17,12 +28,6 @@
"description": "Secret used to connect to OpenVidu Server. This value is required when using the REST API or any server client, as well as when connecting to openvidu-server dashboard", "description": "Secret used to connect to OpenVidu Server. This value is required when using the REST API or any server client, as well as when connecting to openvidu-server dashboard",
"defaultValue": "MY_SECRET" "defaultValue": "MY_SECRET"
}, },
{
"name": "OPENVIDU_PUBLICURL",
"type": "java.lang.String",
"description": "URL to connect clients to OpenVidu Server. This must be the full IP of your OpenVidu Server, including protocol, host and port (for example: https://my.openvidu.server.ip:4443). If no port argument is provided, 'server.port' param will be appended to it",
"defaultValue": "local"
},
{ {
"name": "OPENVIDU_CDR", "name": "OPENVIDU_CDR",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
@ -79,7 +84,7 @@
{ {
"name": "OPENVIDU_RECORDING_COMPOSED_URL", "name": "OPENVIDU_RECORDING_COMPOSED_URL",
"type": "java.lang.String", "type": "java.lang.String",
"description": "URL the composed-video recording dockerized Chrome will use to connect to the recording layouts inside OpenVidu Server host. This will affect all video recording layouts (default one BEST_FIT, all CUSTOM layouts). This allows changing the default URL, which is 'OPENVIDU_PUBLICURL', for those cases where OpenVidu Server host does not allow back and forth connections using the public url from inside the host", "description": "URL the composed-video recording dockerized Chrome will use to connect to the recording layouts inside OpenVidu Server host. This will affect all video recording layouts (default one BEST_FIT, all CUSTOM layouts). This allows changing the default URL, which is the public URL 'https://DOMAIN_OR_PUBLIC_IP:HTTPS_PORT/', for those cases where OpenVidu Server host does not allow back and forth connections using the public url from inside the host",
"defaultValue": "" "defaultValue": ""
}, },
{ {

View File

@ -0,0 +1 @@
HTTPS_PORT=4443

View File

@ -1,22 +0,0 @@
spring.profiles.active: docker
server.address: 0.0.0.0
server.port: 4443
server.ssl.enabled: true
server.ssl.key-store: classpath:openvidu-selfsigned.jks
server.ssl.key-store-password: openvidu
server.ssl.key-store-type: JKS
server.ssl.key-alias: openvidu-selfsigned
KMS_URIS=["ws://localhost:8888/kurento"]
OPENVIDU_SECRET: MY_SECRET
OPENVIDU_PUBLICURL: local
OPENVIDU_CDR: false
OPENVIDU_RECORDING: false
OPENVIDU_RECORDING_VERSION: 2.9.0
OPENVIDU_RECORDING_PATH: /opt/openvidu/recordings
OPENVIDU_RECORDING_PUBLIC_ACCESS: false
OPENVIDU_RECORDING_NOTIFICATION: publisher_moderator
OPENVIDU_RECORDING_CUSTOM_LAYOUT: /opt/openvidu/custom-layout
OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT: 120

View File

@ -1,6 +1,5 @@
server.address=0.0.0.0 server.address=0.0.0.0
server.ssl.enabled=true server.ssl.enabled=true
server.port=4443
server.ssl.key-store=classpath:openvidu-selfsigned.jks server.ssl.key-store=classpath:openvidu-selfsigned.jks
server.ssl.key-store-password=openvidu server.ssl.key-store-password=openvidu
server.ssl.key-store-type=JKS server.ssl.key-store-type=JKS
@ -10,11 +9,11 @@ logging.level.root=info
spring.main.allow-bean-definition-overriding=true spring.main.allow-bean-definition-overriding=true
DOTENV_PATH=. DOTENV_PATH=.
DOMAIN_OR_PUBLIC_IP=localhost
HTTPS_PORT=443
CERTIFICATE_TYPE=selfsigned CERTIFICATE_TYPE=selfsigned
KMS_URIS=["ws://localhost:8888/kurento"] KMS_URIS=["ws://localhost:8888/kurento"]
OPENVIDU_PUBLICURL=local
OPENVIDU_SECRET=MY_SECRET OPENVIDU_SECRET=MY_SECRET
OPENVIDU_CDR=false OPENVIDU_CDR=false

View File

@ -1,8 +1,8 @@
server.port: 4443
server.address: 0.0.0.0 server.address: 0.0.0.0
server.ssl.enabled: false server.ssl.enabled: false
KMS_URIS=[\"ws://localhost:8888/kurento\"] DOMAIN_OR_PUBLIC_IP=localhost
HTTPS_PORT=4443
OPENVIDU_SECRET=MY_SECRET
OPENVIDU_SECRET: MY_SECRET KMS_URIS=[\"ws://localhost:8888/kurento\"]
OPENVIDU_PUBLICURL: local

View File

@ -1,6 +1,5 @@
server.address=0.0.0.0 server.address=0.0.0.0
server.ssl.enabled=true server.ssl.enabled=true
server.port=4443
server.ssl.key-store=classpath:openvidu-selfsigned.jks server.ssl.key-store=classpath:openvidu-selfsigned.jks
server.ssl.key-store-password=openvidu server.ssl.key-store-password=openvidu
server.ssl.key-store-type=JKS server.ssl.key-store-type=JKS
@ -11,7 +10,9 @@ spring.main.allow-bean-definition-overriding=true
KMS_URIS=["ws://localhost:8888/kurento"] KMS_URIS=["ws://localhost:8888/kurento"]
OPENVIDU_PUBLICURL=local DOMAIN_OR_PUBLIC_IP=localhost
HTTPS_PORT=4443
OPENVIDU_SECRET=MY_SECRET OPENVIDU_SECRET=MY_SECRET
OPENVIDU_CDR=false OPENVIDU_CDR=false

View File

@ -70,10 +70,10 @@ node('container') {
sh(script: '''#!/bin/bash sh(script: '''#!/bin/bash
if [ "$DOCKER_RECORDING_VERSION" != "default" ]; then if [ "$DOCKER_RECORDING_VERSION" != "default" ]; then
echo "Using custom openvidu-recording tag: $DOCKER_RECORDING_VERSION" echo "Using custom openvidu-recording tag: $DOCKER_RECORDING_VERSION"
cd openvidu/openvidu-server/target && java -jar -DOPENVIDU_PUBLICURL=https://172.17.0.1:4443/ -DOPENVIDU_RECORDING=true -DOPENVIDU_RECORDING_VERSION=$DOCKER_RECORDING_VERSION -DOPENVIDU_WEBHOOK=true -DOPENVIDU_WEBHOOK_ENDPOINT=http://127.0.0.1:7777/webhook openvidu-server-*.jar &> openvidu-server.log & cd openvidu/openvidu-server/target && java -jar -DDOMAIN_OR_PUBLIC_IP=172.17.0.1 -DHTTPS_PORT=4443 -DOPENVIDU_RECORDING=true -DOPENVIDU_RECORDING_VERSION=$DOCKER_RECORDING_VERSION -DOPENVIDU_WEBHOOK=true -DOPENVIDU_WEBHOOK_ENDPOINT=http://127.0.0.1:7777/webhook openvidu-server-*.jar &> openvidu-server.log &
else else
echo "Using default openvidu-recording tag" echo "Using default openvidu-recording tag"
cd openvidu/openvidu-server/target && java -jar -DOPENVIDU_PUBLICURL=https://172.17.0.1:4443/ -DOPENVIDU_RECORDING=true -DOPENVIDU_WEBHOOK=true -DOPENVIDU_WEBHOOK_ENDPOINT=http://127.0.0.1:7777/webhook openvidu-server-*.jar &> openvidu-server.log & cd openvidu/openvidu-server/target && java -jar -DDOMAIN_OR_PUBLIC_IP=172.17.0.1 -DHTTPS_PORT=4443 -DOPENVIDU_RECORDING=true -DOPENVIDU_WEBHOOK=true -DOPENVIDU_WEBHOOK_ENDPOINT=http://127.0.0.1:7777/webhook openvidu-server-*.jar &> openvidu-server.log &
fi fi
'''.stripIndent()) '''.stripIndent())
sh 'until $(curl --insecure --output /dev/null --silent --head --fail https://OPENVIDUAPP:MY_SECRET@localhost:4443/); do echo "Waiting for openvidu-server..."; sleep 2; done' sh 'until $(curl --insecure --output /dev/null --silent --head --fail https://OPENVIDUAPP:MY_SECRET@localhost:4443/); do echo "Waiting for openvidu-server..."; sleep 2; done'

View File

@ -2636,7 +2636,7 @@ public class OpenViduTestAppE2eTest {
/** GET /config **/ /** GET /config **/
restClient.rest(HttpMethod.GET, "/config", null, HttpStatus.SC_OK, true, restClient.rest(HttpMethod.GET, "/config", null, HttpStatus.SC_OK, true,
"{'VERSION':'STR','OPENVIDU_PUBLICURL':'STR','OPENVIDU_CDR':false,'OPENVIDU_STREAMS_VIDEO_MAX_RECV_BANDWIDTH':0,'OPENVIDU_STREAMS_VIDEO_MIN_RECV_BANDWIDTH':0," "{'VERSION':'STR','DOMAIN_OR_PUBLIC_IP':'STR','HTTPS_PORT':0,'OPENVIDU_PUBLICURL':'STR','OPENVIDU_CDR':false,'OPENVIDU_STREAMS_VIDEO_MAX_RECV_BANDWIDTH':0,'OPENVIDU_STREAMS_VIDEO_MIN_RECV_BANDWIDTH':0,"
+ "'OPENVIDU_STREAMS_VIDEO_MAX_SEND_BANDWIDTH':0,'OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH':0,'OPENVIDU_SESSIONS_GARBAGE_INTERVAL':0,'OPENVIDU_SESSIONS_GARBAGE_THRESHOLD':0," + "'OPENVIDU_STREAMS_VIDEO_MAX_SEND_BANDWIDTH':0,'OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH':0,'OPENVIDU_SESSIONS_GARBAGE_INTERVAL':0,'OPENVIDU_SESSIONS_GARBAGE_THRESHOLD':0,"
+ "'OPENVIDU_RECORDING':false,'OPENVIDU_RECORDING_VERSION':'STR','OPENVIDU_RECORDING_PATH':'STR','OPENVIDU_RECORDING_PUBLIC_ACCESS':false,'OPENVIDU_RECORDING_NOTIFICATION':'STR'," + "'OPENVIDU_RECORDING':false,'OPENVIDU_RECORDING_VERSION':'STR','OPENVIDU_RECORDING_PATH':'STR','OPENVIDU_RECORDING_PUBLIC_ACCESS':false,'OPENVIDU_RECORDING_NOTIFICATION':'STR',"
+ "'OPENVIDU_RECORDING_CUSTOM_LAYOUT':'STR','OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT':0,'OPENVIDU_WEBHOOK':false,'OPENVIDU_WEBHOOK_ENDPOINT':'STR','OPENVIDU_WEBHOOK_HEADERS':[]," + "'OPENVIDU_RECORDING_CUSTOM_LAYOUT':'STR','OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT':0,'OPENVIDU_WEBHOOK':false,'OPENVIDU_WEBHOOK_ENDPOINT':'STR','OPENVIDU_WEBHOOK_HEADERS':[],"