openvidu-server, deployment: Remove redis for coturn. Now credentials are generated using https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00

pull/713/head
cruizba 2022-04-06 18:37:11 +02:00
parent e9cdb7b131
commit ac5485ddc0
23 changed files with 46 additions and 334 deletions

View File

@ -26,7 +26,6 @@ import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
@ -95,6 +94,7 @@ public class IceServerProperties {
private String username; private String username;
private String credential; private String credential;
private String staticAuthSecret; private String staticAuthSecret;
private boolean ignoreEmptyUrl = false;
/** /**
* Set the url for the ICE Server you want to use. * Set the url for the ICE Server you want to use.
@ -141,6 +141,11 @@ public class IceServerProperties {
return this; return this;
} }
public IceServerProperties.Builder ignoreEmptyUrl(boolean ignore) {
this.ignoreEmptyUrl = true;
return this;
}
public IceServerProperties.Builder clone() { public IceServerProperties.Builder clone() {
return new Builder().url(this.url) return new Builder().url(this.url)
.username(this.username) .username(this.username)
@ -158,6 +163,18 @@ public class IceServerProperties {
* </ul> * </ul>
*/ */
public IceServerProperties build() throws IllegalArgumentException { public IceServerProperties build() throws IllegalArgumentException {
if (this.ignoreEmptyUrl) {
if (this.staticAuthSecret != null && this.username == null && this.credential == null) {
try {
this.generateTURNCredentials();
return new IceServerProperties(this.url, this.username, this.credential);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new IllegalArgumentException("Error while generating credentials: " + e.getMessage());
}
} else {
throw new IllegalArgumentException("ignoreEmptyUrl=true can only be used with staticAuthSecret defined");
}
}
if (this.url == null) { if (this.url == null) {
throw new IllegalArgumentException("External turn url cannot be null"); throw new IllegalArgumentException("External turn url cannot be null");
} }

View File

@ -65,24 +65,10 @@ services:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
redis:
image: openvidu/openvidu-redis:4.0.0
restart: always
network_mode: host
environment:
- REDIS_PASSWORD=${OPENVIDU_SECRET}
logging:
options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
coturn: coturn:
image: openvidu/openvidu-coturn:6.0.0 image: openvidu/openvidu-coturn:6.0.0
restart: on-failure restart: on-failure
network_mode: host network_mode: host
environment:
- REDIS_IP=127.0.0.1
- DB_NAME=0
- DB_PASSWORD=${OPENVIDU_SECRET}
command: command:
- --log-file=stdout - --log-file=stdout
- --listening-port=${COTURN_PORT:-3478} - --listening-port=${COTURN_PORT:-3478}
@ -92,6 +78,8 @@ services:
- --max-port=${COTURN_MAX_PORT:-65535} - --max-port=${COTURN_MAX_PORT:-65535}
- --realm=openvidu - --realm=openvidu
- --verbose - --verbose
- --use-auth-secret
- --static-auth-secret=${OPENVIDU_SECRET}
logging: logging:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"

View File

@ -37,10 +37,6 @@ output:
elasticsearch: elasticsearch:
hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"] hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"]
indices: indices:
- index: "filebeat-redis-%{+yyyy.MM.dd}"
when.or:
- contains:
container.image.name: openvidu/openvidu-redis
- index: "filebeat-replication-manager-%{+yyyy.MM.dd}" - index: "filebeat-replication-manager-%{+yyyy.MM.dd}"
when.or: when.or:
- contains: - contains:

View File

@ -83,26 +83,12 @@ services:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
redis:
image: openvidu/openvidu-redis:4.0.0
restart: always
network_mode: host
environment:
- REDIS_PASSWORD=${OPENVIDU_SECRET}
logging:
options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
coturn: coturn:
image: openvidu/openvidu-coturn:6.0.0 image: openvidu/openvidu-coturn:6.0.0
restart: on-failure restart: on-failure
network_mode: host network_mode: host
env_file: env_file:
- .env - .env
environment:
- REDIS_IP=127.0.0.1
- DB_NAME=0
- DB_PASSWORD=${OPENVIDU_SECRET}
command: command:
- --log-file=stdout - --log-file=stdout
- --external-ip=$$(detect-external-ip) - --external-ip=$$(detect-external-ip)
@ -113,6 +99,8 @@ services:
- --max-port=${COTURN_MAX_PORT:-65535} - --max-port=${COTURN_MAX_PORT:-65535}
- --realm=openvidu - --realm=openvidu
- --verbose - --verbose
- --use-auth-secret
- --static-auth-secret=${OPENVIDU_SECRET}
logging: logging:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"

View File

@ -37,10 +37,6 @@ output:
elasticsearch: elasticsearch:
hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"] hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"]
indices: indices:
- index: "filebeat-redis-%{+yyyy.MM.dd}"
when.or:
- contains:
container.image.name: openvidu/openvidu-redis
- index: "filebeat-nginx-%{+yyyy.MM.dd}" - index: "filebeat-nginx-%{+yyyy.MM.dd}"
when.or: when.or:
- contains: - contains:

View File

@ -52,27 +52,12 @@ services:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
redis:
image: openvidu/openvidu-redis:4.0.0
restart: always
network_mode: host
environment:
- REDIS_PASSWORD=${OPENVIDU_SECRET}
- REDIS_BINDING=127.0.0.1
logging:
options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"
coturn: coturn:
image: openvidu/openvidu-coturn:6.0.0 image: openvidu/openvidu-coturn:6.0.0
restart: on-failure restart: on-failure
network_mode: host network_mode: host
env_file: env_file:
- .env - .env
environment:
- REDIS_IP=127.0.0.1
- DB_NAME=0
- DB_PASSWORD=${OPENVIDU_SECRET}
command: command:
- --log-file=stdout - --log-file=stdout
- --external-ip=$$(detect-external-ip) - --external-ip=$$(detect-external-ip)
@ -83,6 +68,8 @@ services:
- --max-port=${COTURN_MAX_PORT:-65535} - --max-port=${COTURN_MAX_PORT:-65535}
- --realm=openvidu - --realm=openvidu
- --verbose - --verbose
- --use-auth-secret
- --static-auth-secret=${OPENVIDU_SECRET}
logging: logging:
options: options:
max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}"

View File

@ -1,7 +1,4 @@
#!/bin/sh #!/bin/sh
if [ ! -z "${REDIS_IP}" ] && [ ! -z "${DB_NAME}" ] && [ ! -z "${DB_PASSWORD}" ]; then
echo "redis-userdb=\"ip=${REDIS_IP} dbname=${DB_NAME} password=${DB_PASSWORD} connect_timeout=30\"" > turnserver.conf
fi
# If command starts with an option, prepend with turnserver binary. # If command starts with an option, prepend with turnserver binary.
if [ "${1:0:1}" == '-' ]; then if [ "${1:0:1}" == '-' ]; then

View File

@ -1,7 +0,0 @@
FROM redis:6.2.6-alpine
COPY ./entrypoint.sh /usr/local/bin
RUN chmod +x /usr/local/bin/entrypoint.sh
CMD /usr/local/bin/entrypoint.sh

View File

@ -1,6 +0,0 @@
VERSION=$1
if [[ ! -z $VERSION ]]; then
docker build --pull --no-cache --rm=true -t openvidu/openvidu-redis:$VERSION .
else
echo "Error: You need to specify a version as first argument"
fi

View File

@ -1,30 +0,0 @@
#!/bin/sh
if [ -f /proc/net/if_inet6 ]; then
[ -z "${REDIS_BINDING}" ] && REDIS_BINDING="127.0.0.1 ::1"
else
[ -z "${REDIS_BINDING}" ] && REDIS_BINDING="127.0.0.1"
fi
printf "\n"
printf "\n ======================================="
printf "\n = REDIS CONF ="
printf "\n ======================================="
printf "\n"
printf "\n REDIS_BINDING: %s" "${REDIS_BINDING}"
printf "\n REDIS_PASSWORD: %s" "${REDIS_PASSWORD}"
mkdir -p /usr/local/etc/redis
cat>/usr/local/etc/redis/redis.conf<<EOF
bind ${REDIS_BINDING}
requirepass ${REDIS_PASSWORD}
EOF
printf "\n"
printf "\n ======================================="
printf "\n = START REDIS ="
printf "\n ======================================="
printf "\n"
redis-server /usr/local/etc/redis/redis.conf

View File

@ -6,8 +6,6 @@ RUN apt-get update && apt-get install -y \
curl \ curl \
wget \ wget \
openjdk-11-jre \ openjdk-11-jre \
coturn \
redis-tools \
jq \ jq \
docker.io \ docker.io \
ethtool \ ethtool \

View File

@ -6,8 +6,6 @@ RUN apt-get update && apt-get install -y \
curl \ curl \
wget \ wget \
openjdk-11-jre \ openjdk-11-jre \
coturn \
redis-tools \
dnsutils \ dnsutils \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

View File

@ -54,7 +54,6 @@ import io.openvidu.server.core.SessionManager;
import io.openvidu.server.core.TokenGenerator; import io.openvidu.server.core.TokenGenerator;
import io.openvidu.server.core.TokenRegister; import io.openvidu.server.core.TokenRegister;
import io.openvidu.server.coturn.CoturnCredentialsService; import io.openvidu.server.coturn.CoturnCredentialsService;
import io.openvidu.server.coturn.CoturnCredentialsServiceFactory;
import io.openvidu.server.kurento.core.KurentoParticipantEndpointConfig; import io.openvidu.server.kurento.core.KurentoParticipantEndpointConfig;
import io.openvidu.server.kurento.core.KurentoSessionEventsHandler; import io.openvidu.server.kurento.core.KurentoSessionEventsHandler;
import io.openvidu.server.kurento.core.KurentoSessionManager; import io.openvidu.server.kurento.core.KurentoSessionManager;
@ -125,7 +124,7 @@ public class OpenViduServer implements JsonRpcConfigurer {
@ConditionalOnMissingBean @ConditionalOnMissingBean
@DependsOn("openviduConfig") @DependsOn("openviduConfig")
public CoturnCredentialsService coturnCredentialsService(OpenviduConfig openviduConfig) { public CoturnCredentialsService coturnCredentialsService(OpenviduConfig openviduConfig) {
return new CoturnCredentialsServiceFactory().getCoturnCredentialsService(openviduConfig.getSpringProfile()); return new CoturnCredentialsService();
} }
@Bean @Bean

View File

@ -216,8 +216,6 @@ public class OpenviduConfig {
public static String finalUrl; public static String finalUrl;
private boolean isTurnadminAvailable = false;
// Media Server properties // Media Server properties
private MediaServer mediaServerInfo = MediaServer.kurento; private MediaServer mediaServerInfo = MediaServer.kurento;
@ -416,14 +414,6 @@ public class OpenviduConfig {
finalUrl = finalUrlParam.endsWith("/") ? (finalUrlParam) : (finalUrlParam + "/"); finalUrl = finalUrlParam.endsWith("/") ? (finalUrlParam) : (finalUrlParam + "/");
} }
public boolean isTurnadminAvailable() {
return this.isTurnadminAvailable;
}
public void setTurnadminAvailable(boolean available) {
this.isTurnadminAvailable = available;
}
public boolean areMediaNodesPublicIpsDefined() { public boolean areMediaNodesPublicIpsDefined() {
return !this.mediaNodesPublicIps.isEmpty(); return !this.mediaNodesPublicIps.isEmpty();
} }

View File

@ -361,8 +361,7 @@ public abstract class SessionManager {
public Token newTokenForInsecureUser(Session session, String token, ConnectionProperties connectionProperties) public Token newTokenForInsecureUser(Session session, String token, ConnectionProperties connectionProperties)
throws Exception { throws Exception {
Token tokenObj = new Token(token, session.getSessionId(), connectionProperties, Token tokenObj = new Token(token, session.getSessionId(), connectionProperties, this.coturnCredentialsService.createUser());
this.openviduConfig.isTurnadminAvailable() ? this.coturnCredentialsService.createUser() : null);
session.storeToken(tokenObj); session.storeToken(tokenObj);
return tokenObj; return tokenObj;
} }

View File

@ -50,10 +50,7 @@ public class TokenGenerator {
token += "?sessionId=" + sessionId; token += "?sessionId=" + sessionId;
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(15); + RandomStringUtils.randomAlphanumeric(15);
TurnCredentials turnCredentials = null; TurnCredentials turnCredentials = coturnCredentialsService.createUser();
if (this.openviduConfig.isTurnadminAvailable()) {
turnCredentials = coturnCredentialsService.createUser();
}
ConnectionProperties.Builder connectionPropertiesBuilder = new ConnectionProperties.Builder() ConnectionProperties.Builder connectionPropertiesBuilder = new ConnectionProperties.Builder()
.type(ConnectionType.WEBRTC).data(serverMetadata).record(record).role(role) .type(ConnectionType.WEBRTC).data(serverMetadata).record(record).role(role)
.kurentoOptions(kurentoOptions); .kurentoOptions(kurentoOptions);

View File

@ -1,121 +0,0 @@
/*
* (C) Copyright 2017-2022 OpenVidu (https://openvidu.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.openvidu.server.coturn;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.RandomStringUtils;
import io.openvidu.server.utils.CommandExecutor;
public class BashCoturnCredentialsService extends CoturnCredentialsService {
private String logPath;
private AtomicLong logCounter = new AtomicLong(0);
private final long LOG_LIMIT = 30;
@PostConstruct
private void initialize() {
try {
String response = CommandExecutor.execCommand(10000, "/bin/sh", "-c",
"turnadmin -l -N " + this.coturnDatabaseString);
if (response.contains("turnadmin: not found")) {
// No coturn installed in the host machine
log.warn("No COTURN server is installed in the host machine. Response: " + response);
log.error("No COTURN server will be automatically configured for clients");
} else if (response.contains("Cannot initialize Redis DB connection")) {
log.warn("Redis DB is not accesible with connection string " + this.coturnDatabaseString);
log.error("No COTURN server will be automatically configured for clients");
} else {
log.info("COTURN IP: " + this.openviduConfig.getCoturnIp());
log.info("COTURN PORT: " + this.openviduConfig.getCoturnPort());
log.info("COTURN Redis DB accessible with string " + this.coturnDatabaseString);
log.info("Cleaning COTURN DB...");
if (response.contains("log file opened")) {
String[] logArray = response.split("\\r?\\n")[0].split("\\s+");
String logFile = logArray[logArray.length - 1];
this.logPath = logFile.substring(0, logFile.lastIndexOf('/') + 1);
log.info("Path of COTURN log files: " + this.logPath);
}
response = CommandExecutor.execCommand(10000, "/bin/sh", "-c",
"redis-cli -a " + this.openviduConfig.getCoturnDatabasePassword() + " -n "
+ this.openviduConfig.getCoturnDatabaseDbname() + " flushdb");
String response2 = CommandExecutor.execCommand(10000, "/bin/sh", "-c",
"redis-cli -a " + this.openviduConfig.getCoturnDatabasePassword() + " -n "
+ this.openviduConfig.getCoturnDatabaseDbname() + " --scan --pattern '*'");
if ("OK".equals(response) && response2.isEmpty()) {
log.info("COTURN DB is now empty");
} else {
log.error("COTURN DB is not empty");
}
this.openviduConfig.setTurnadminAvailable(true);
log.info("Using COTURN credentials service for BASH environment");
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
@Override
public TurnCredentials createUser() throws IOException, InterruptedException {
TurnCredentials credentials = null;
log.info("Creating COTURN user");
String user = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
String pass = RandomStringUtils.randomAlphanumeric(6).toLowerCase();
String command = "turnadmin -a -u " + user + " -r openvidu -p " + pass + " -N " + this.coturnDatabaseString;
String response = CommandExecutor.execCommand(10000, "/bin/sh", "-c", command);
if (response.contains("connection success: " + this.trimmedCoturnDatabaseString)) {
credentials = new TurnCredentials(user, pass);
this.cleanTurnLogFiles();
log.info("COTURN user created: true");
} else {
log.info("COTURN user created: false");
}
return credentials;
}
@Override
public boolean deleteUser(String user) {
boolean userRemoved = false;
log.info("Deleting COTURN user");
String command = "turnadmin -d -u " + user + " -r openvidu -N " + this.coturnDatabaseString;
String response = "";
try {
response = CommandExecutor.execCommand(10000, "/bin/sh", "-c", command);
this.cleanTurnLogFiles();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
userRemoved = response.contains("connection success: " + this.trimmedCoturnDatabaseString);
log.info("COTURN user deleted: " + userRemoved);
return userRemoved;
}
private void cleanTurnLogFiles() throws IOException, InterruptedException {
if (this.logCounter.incrementAndGet() > LOG_LIMIT) {
CommandExecutor.execCommand(10000, "/bin/sh", "-c", "rm " + this.logPath + "turn_*.log");
log.info("Garbage collector cleaning turn log files at path " + this.logPath);
this.logCounter.set(0);
}
}
}

View File

@ -1,48 +1,28 @@
/*
* (C) Copyright 2017-2022 OpenVidu (https://openvidu.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.openvidu.server.coturn; package io.openvidu.server.coturn;
import javax.annotation.PostConstruct; import io.openvidu.java.client.IceServerProperties;
import io.openvidu.server.config.OpenviduConfig;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import io.openvidu.server.config.OpenviduConfig; /**
* This class implements the proposed standard https://datatracker.ietf.org/doc/html/draft-uberti-rtcweb-turn-rest-00
* for obtaining access to TURN services via ephemeral (i.e. time-limited) credentials.
*/
public class CoturnCredentialsService {
public abstract class CoturnCredentialsService { protected static final Logger log = LoggerFactory.getLogger(CoturnCredentialsService.class);
protected static final Logger log = LoggerFactory.getLogger(CoturnCredentialsService.class); @Autowired
protected OpenviduConfig openviduConfig;
@Autowired public TurnCredentials createUser() {
protected OpenviduConfig openviduConfig; IceServerProperties iceServerProperties = new IceServerProperties.Builder()
.ignoreEmptyUrl(true)
protected String coturnDatabaseString; .staticAuthSecret(openviduConfig.getOpenViduSecret())
protected String trimmedCoturnDatabaseString; .build();
return new TurnCredentials(iceServerProperties.getUsername(), iceServerProperties.getCredential());
public abstract TurnCredentials createUser() throws Exception; }
public abstract boolean deleteUser(String user);
@PostConstruct
protected void initDatabse() {
this.coturnDatabaseString = this.openviduConfig.getCoturnDatabaseString();
this.trimmedCoturnDatabaseString = this.coturnDatabaseString.replaceAll("^\"|\"$", "");
}
} }

View File

@ -1,31 +0,0 @@
/*
* (C) Copyright 2017-2022 OpenVidu (https://openvidu.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.openvidu.server.coturn;
public class CoturnCredentialsServiceFactory {
public CoturnCredentialsService getCoturnCredentialsService(String springProfile) {
if (!"docker".equals(springProfile)) {
return new BashCoturnCredentialsService();
} else {
// TODO: return other options
return new BashCoturnCredentialsService();
}
}
}

View File

@ -1,17 +0,0 @@
package io.openvidu.server.coturn;
public class DockerCoturnCredentialsService extends CoturnCredentialsService {
@Override
public TurnCredentials createUser() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean deleteUser(String user) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -227,11 +227,6 @@ public class KurentoSessionManager extends SessionManager {
Participant p = sessionidParticipantpublicidParticipant.get(sessionId) Participant p = sessionidParticipantpublicidParticipant.get(sessionId)
.remove(participant.getParticipantPublicId()); .remove(participant.getParticipantPublicId());
if (p != null && p.getToken() != null && p.getToken().getTurnCredentials() != null
&& this.openviduConfig.isTurnadminAvailable()) {
this.coturnCredentialsService.deleteUser(p.getToken().getTurnCredentials().getUsername());
}
// TODO: why is this necessary?? // TODO: why is this necessary??
if (p != null && insecureUsers.containsKey(p.getParticipantPrivateId())) { if (p != null && insecureUsers.containsKey(p.getParticipantPrivateId())) {
boolean stillParticipant = false; boolean stillParticipant = false;

View File

@ -300,8 +300,7 @@ public abstract class MediaEndpoint {
public void onSuccess(WebRtcEndpoint result) throws Exception { public void onSuccess(WebRtcEndpoint result) throws Exception {
webEndpoint = result; webEndpoint = result;
if (openviduConfig.getCoturnIp() != null && !openviduConfig.getCoturnIp().isEmpty() if (openviduConfig.getCoturnIp() != null && !openviduConfig.getCoturnIp().isEmpty()) {
&& openviduConfig.isTurnadminAvailable()) {
webEndpoint.setStunServerAddress(openviduConfig.getCoturnIp()); webEndpoint.setStunServerAddress(openviduConfig.getCoturnIp());
webEndpoint.setStunServerPort(openviduConfig.getCoturnPort()); webEndpoint.setStunServerPort(openviduConfig.getCoturnPort());
} }

View File

@ -122,7 +122,7 @@ def removeStrandedContainers(removeTestingContainers) {
"budtmo/docker-android" "budtmo/docker-android"
"openvidu/mediasoup-controller:" "openvidu/mediasoup-controller:"
"openvidu/openvidu-server-pro:" "openvidu/openvidu-server-pro:"
"openvidu/openvidu-redis:" "redis:"
"openvidu/openvidu-coturn:" "openvidu/openvidu-coturn:"
"openvidu/openvidu-proxy:" "openvidu/openvidu-proxy:"
"openvidu/replication-manager:" "openvidu/replication-manager:"