mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: OpenviduConfig refactoring
parent
de2153fe0f
commit
3ed4ae0856
|
@ -18,12 +18,9 @@
|
||||||
package io.openvidu.server;
|
package io.openvidu.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
|
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
|
||||||
import org.kurento.jsonrpc.server.JsonRpcConfigurer;
|
import org.kurento.jsonrpc.server.JsonRpcConfigurer;
|
||||||
import org.kurento.jsonrpc.server.JsonRpcHandlerRegistry;
|
import org.kurento.jsonrpc.server.JsonRpcHandlerRegistry;
|
||||||
|
@ -38,8 +35,6 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
import io.openvidu.client.OpenViduException;
|
|
||||||
import io.openvidu.client.OpenViduException.Code;
|
|
||||||
import io.openvidu.server.cdr.CDRLogger;
|
import io.openvidu.server.cdr.CDRLogger;
|
||||||
import io.openvidu.server.cdr.CDRLoggerFile;
|
import io.openvidu.server.cdr.CDRLoggerFile;
|
||||||
import io.openvidu.server.cdr.CallDetailRecord;
|
import io.openvidu.server.cdr.CallDetailRecord;
|
||||||
|
@ -81,26 +76,45 @@ 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 String publicurlType;
|
||||||
|
public static String wsUrl;
|
||||||
|
public static String httpUrl;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
OpenviduConfig openviduConfig;
|
OpenviduConfig openviduConfig;
|
||||||
|
|
||||||
public static final String KMSS_URIS_PROPERTY = "kms.uris";
|
|
||||||
|
|
||||||
public static String wsUrl;
|
|
||||||
|
|
||||||
public static String httpUrl;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public KmsManager kmsManager() {
|
public KmsManager kmsManager() {
|
||||||
if (openviduConfig.getKmsUris().isEmpty()) {
|
if (openviduConfig.getKmsUris().isEmpty()) {
|
||||||
throw new IllegalArgumentException(KMSS_URIS_PROPERTY + " should contain at least one kms url");
|
throw new IllegalArgumentException("'kms.uris' should contain at least one KMS url");
|
||||||
}
|
}
|
||||||
String firstKmsWsUri = openviduConfig.getKmsUris().get(0);
|
String firstKmsWsUri = openviduConfig.getKmsUris().get(0);
|
||||||
log.info("OpenVidu Server using one KMS: {}", firstKmsWsUri);
|
log.info("OpenVidu Server using one KMS: {}", firstKmsWsUri);
|
||||||
return new FixedOneKmsManager();
|
return new FixedOneKmsManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public CallDetailRecord cdr() {
|
||||||
|
List<CDRLogger> loggers = new ArrayList<>();
|
||||||
|
if (openviduConfig.isCdrEnabled()) {
|
||||||
|
log.info("OpenVidu CDR is enabled");
|
||||||
|
loggers.add(new CDRLoggerFile());
|
||||||
|
}
|
||||||
|
if (openviduConfig.isWebhookEnabled()) {
|
||||||
|
loggers.add(new CDRLoggerWebhook(openviduConfig));
|
||||||
|
}
|
||||||
|
return new CallDetailRecord(loggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public CoturnCredentialsService coturnCredentialsService() {
|
||||||
|
return new CoturnCredentialsServiceFactory().getCoturnCredentialsService(openviduConfig.getSpringProfile());
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public LoadManager loadManager() {
|
public LoadManager loadManager() {
|
||||||
|
@ -131,20 +145,6 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
||||||
return new KurentoSessionEventsHandler();
|
return new KurentoSessionEventsHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public CallDetailRecord cdr() {
|
|
||||||
List<CDRLogger> loggers = new ArrayList<>();
|
|
||||||
if (openviduConfig.isCdrEnabled()) {
|
|
||||||
log.info("OpenVidu CDR is enabled");
|
|
||||||
loggers.add(new CDRLoggerFile());
|
|
||||||
}
|
|
||||||
if (openviduConfig.isWebhookEnabled()) {
|
|
||||||
loggers.add(new CDRLoggerWebhook(openviduConfig));
|
|
||||||
}
|
|
||||||
return new CallDetailRecord(loggers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public KurentoParticipantEndpointConfig kurentoEndpointConfig() {
|
public KurentoParticipantEndpointConfig kurentoEndpointConfig() {
|
||||||
|
@ -169,12 +169,6 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
||||||
return new DummyRecordingDownloader();
|
return new DummyRecordingDownloader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public CoturnCredentialsService coturnCredentialsService() {
|
|
||||||
return new CoturnCredentialsServiceFactory().getCoturnCredentialsService(openviduConfig.getSpringProfile());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public GeoLocationByIp geoLocationByIp() {
|
public GeoLocationByIp geoLocationByIp() {
|
||||||
|
@ -190,10 +184,10 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
||||||
@Override
|
@Override
|
||||||
public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) {
|
public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) {
|
||||||
registry.addHandler(rpcHandler().withPingWatchdog(true).withInterceptors(new HttpHandshakeInterceptor()),
|
registry.addHandler(rpcHandler().withPingWatchdog(true).withInterceptors(new HttpHandshakeInterceptor()),
|
||||||
"/openvidu");
|
WS_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getContainerIp() throws IOException, InterruptedException {
|
public static String getContainerIp() throws IOException, InterruptedException {
|
||||||
return CommandExecutor.execCommand("/bin/sh", "-c", "hostname -i | awk '{print $1}'");
|
return CommandExecutor.execCommand("/bin/sh", "-c", "hostname -i | awk '{print $1}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,86 +197,14 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
||||||
SpringApplication.run(OpenViduServer.class, args);
|
SpringApplication.run(OpenViduServer.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() throws MalformedURLException, InterruptedException {
|
|
||||||
String publicUrl = this.openviduConfig.getOpenViduPublicUrl();
|
|
||||||
String type = publicUrl;
|
|
||||||
|
|
||||||
switch (publicUrl) {
|
|
||||||
case "docker":
|
|
||||||
try {
|
|
||||||
String containerIp = getContainerIp();
|
|
||||||
OpenViduServer.wsUrl = "wss://" + containerIp + ":" + openviduConfig.getServerPort();
|
|
||||||
} catch (Exception e) {
|
|
||||||
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:
|
|
||||||
|
|
||||||
type = "custom";
|
|
||||||
|
|
||||||
if (publicUrl.startsWith("https://")) {
|
|
||||||
OpenViduServer.wsUrl = publicUrl.replace("https://", "wss://");
|
|
||||||
} else if (publicUrl.startsWith("http://")) {
|
|
||||||
OpenViduServer.wsUrl = publicUrl.replace("http://", "wss://");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!OpenViduServer.wsUrl.startsWith("wss://")) {
|
|
||||||
OpenViduServer.wsUrl = "wss://" + OpenViduServer.wsUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpenViduServer.wsUrl == null) {
|
|
||||||
type = "local";
|
|
||||||
OpenViduServer.wsUrl = "wss://localhost:" + openviduConfig.getServerPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpenViduServer.wsUrl.endsWith("/")) {
|
|
||||||
OpenViduServer.wsUrl = OpenViduServer.wsUrl.substring(0, OpenViduServer.wsUrl.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.openviduConfig.isRecordingModuleEnabled()) {
|
|
||||||
try {
|
|
||||||
this.recordingManager().initializeRecordingManager();
|
|
||||||
} catch (OpenViduException e) {
|
|
||||||
String finalErrorMessage = "";
|
|
||||||
if (e.getCodeValue() == Code.DOCKER_NOT_FOUND.getValue()) {
|
|
||||||
finalErrorMessage = "Error connecting to Docker daemon. Enabling OpenVidu recording module requires Docker";
|
|
||||||
} else if (e.getCodeValue() == Code.RECORDING_PATH_NOT_VALID.getValue()) {
|
|
||||||
finalErrorMessage = "Error initializing recording path \""
|
|
||||||
+ this.openviduConfig.getOpenViduRecordingPath()
|
|
||||||
+ "\" set with system property \"openvidu.recording.path\"";
|
|
||||||
} else if (e.getCodeValue() == Code.RECORDING_FILE_EMPTY_ERROR.getValue()) {
|
|
||||||
finalErrorMessage = "Error initializing recording custom layouts path \""
|
|
||||||
+ this.openviduConfig.getOpenviduRecordingCustomLayout()
|
|
||||||
+ "\" set with system property \"openvidu.recording.custom-layout\"";
|
|
||||||
}
|
|
||||||
log.error(finalErrorMessage + ". Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String finalUrl = OpenViduServer.wsUrl.replaceFirst("wss://", "https://").replaceFirst("ws://", "http://");
|
|
||||||
openviduConfig.setFinalUrl(finalUrl);
|
|
||||||
httpUrl = openviduConfig.getFinalUrl();
|
|
||||||
log.info("OpenVidu Server using " + type + " URL: [" + OpenViduServer.wsUrl + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
public void whenReady() {
|
public void whenReady() {
|
||||||
|
log.info("OpenVidu Server listening for client websocket connections on"
|
||||||
|
+ (OpenViduServer.publicurlType.isEmpty() ? "" : (" " + OpenViduServer.publicurlType)) + " url "
|
||||||
|
+ OpenViduServer.wsUrl + WS_PATH);
|
||||||
final String NEW_LINE = System.lineSeparator();
|
final String NEW_LINE = System.lineSeparator();
|
||||||
String str = NEW_LINE + NEW_LINE + " ACCESS IP " + NEW_LINE + "-------------------------"
|
String str = NEW_LINE + NEW_LINE + " OPENVIDU SERVER IP " + NEW_LINE + "--------------------------"
|
||||||
+ NEW_LINE + httpUrl + NEW_LINE + "-------------------------" + NEW_LINE;
|
+ NEW_LINE + httpUrl + NEW_LINE + "--------------------------" + NEW_LINE;
|
||||||
log.info(str);
|
log.info(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,18 @@ package io.openvidu.server.config;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
@ -46,18 +52,42 @@ import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
import io.openvidu.java.client.OpenViduRole;
|
import io.openvidu.java.client.OpenViduRole;
|
||||||
|
import io.openvidu.server.OpenViduServer;
|
||||||
import io.openvidu.server.cdr.CDREventName;
|
import io.openvidu.server.cdr.CDREventName;
|
||||||
|
import io.openvidu.server.recording.RecordingNotification;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class OpenviduConfig {
|
public class OpenviduConfig {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(OpenviduConfig.class);
|
private static final Logger log = LoggerFactory.getLogger(OpenviduConfig.class);
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_STRING_PROPERTIES = Arrays.asList(new String[] { "openvidu.secret",
|
||||||
|
"openvidu.publicurl", "openvidu.recording.path", "openvidu.recording.notification",
|
||||||
|
"openvidu.recording.custom-layout", "openvidu.webhook.endpoint" });
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_INTEGER_PROPERTIES = Arrays
|
||||||
|
.asList(new String[] { "openvidu.recording.autostop-timeout", "openvidu.streams.video.max-recv-bandwidth",
|
||||||
|
"openvidu.streams.video.min-recv-bandwidth", "openvidu.streams.video.max-send-bandwidth",
|
||||||
|
"openvidu.streams.video.min-send-bandwidth" });
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_BOOLEAN_PROPERTIES = Arrays.asList(new String[] { "openvidu.cdr",
|
||||||
|
"openvidu.recording", "openvidu.recording.public-access", "openvidu.webhook", });
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_ARRAY_PROPERTIES = Arrays
|
||||||
|
.asList(new String[] { "kms.uris", "openvidu.webhook.headers", "openvidu.webhook.events", });
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_PROPERTIES = Stream.of(OPENVIDU_STRING_PROPERTIES,
|
||||||
|
OPENVIDU_INTEGER_PROPERTIES, OPENVIDU_BOOLEAN_PROPERTIES, OPENVIDU_ARRAY_PROPERTIES)
|
||||||
|
.flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
|
|
||||||
|
public static final List<String> OPENVIDU_VALID_PUBLICURL_VALUES = Arrays
|
||||||
|
.asList(new String[] { "local", "docker", "" });
|
||||||
|
|
||||||
@Value("#{'${spring.config.additional-location:}'.length() > 0 ? '${spring.config.additional-location:}' : \"\"}")
|
@Value("#{'${spring.config.additional-location:}'.length() > 0 ? '${spring.config.additional-location:}' : \"\"}")
|
||||||
private String springConfigLocation;
|
private String springConfigLocation;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
BuildProperties buildProperties;
|
private BuildProperties buildProperties;
|
||||||
|
|
||||||
@Value("${kms.uris}")
|
@Value("${kms.uris}")
|
||||||
private String kmsUris;
|
private String kmsUris;
|
||||||
|
@ -87,7 +117,7 @@ public class OpenviduConfig {
|
||||||
private boolean openviduRecordingPublicAccess;
|
private boolean openviduRecordingPublicAccess;
|
||||||
|
|
||||||
@Value("${openvidu.recording.notification}")
|
@Value("${openvidu.recording.notification}")
|
||||||
private String openviduRecordingNotification;
|
private RecordingNotification openviduRecordingNotification;
|
||||||
|
|
||||||
@Value("${openvidu.recording.custom-layout}")
|
@Value("${openvidu.recording.custom-layout}")
|
||||||
private String openviduRecordingCustomLayout;
|
private String openviduRecordingCustomLayout;
|
||||||
|
@ -144,72 +174,9 @@ public class OpenviduConfig {
|
||||||
private List<String> kmsUrisList;
|
private List<String> kmsUrisList;
|
||||||
private List<Header> webhookHeadersList;
|
private List<Header> webhookHeadersList;
|
||||||
private List<CDREventName> webhookEventsList;
|
private List<CDREventName> webhookEventsList;
|
||||||
|
|
||||||
private Properties externalizedProperties;
|
private Properties externalizedProperties;
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
if (!this.springConfigLocation.isEmpty()) {
|
|
||||||
// Properties file has been manually configured in certain path
|
|
||||||
FileSystemResource resource = new FileSystemResource(this.springConfigLocation);
|
|
||||||
try {
|
|
||||||
this.externalizedProperties = PropertiesLoaderUtils.loadProperties(resource);
|
|
||||||
log.info("Properties file found at \"{}\". Content: {}", this.springConfigLocation,
|
|
||||||
externalizedProperties);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Error in 'spring.config.additional-location' system property: {}", e.getMessage());
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
// Check OpenVidu Server write permissions in properties path
|
|
||||||
if (!Files.isWritable(Paths.get(this.springConfigLocation))) {
|
|
||||||
log.warn(
|
|
||||||
"The properties path '{}' set with property 'spring.config.additional-location' is not valid. Reason: OpenVidu Server needs write permissions. Try running command \"sudo chmod 777 {}\". If not, OpenVidu won't be able to overwrite preexisting properties on reboot",
|
|
||||||
this.springConfigLocation, this.springConfigLocation);
|
|
||||||
} else {
|
|
||||||
log.info("OpenVidu Server has write permissions on properties path: {}", this.springConfigLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.kmsUrisList = this.kmsUrisStringToList(this.kmsUris);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error in 'kms.uris' system property: " + e.getMessage());
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
if (this.isWebhookEnabled()) {
|
|
||||||
log.info("OpenVidu Webhook service enabled");
|
|
||||||
try {
|
|
||||||
if (this.openviduWebhookEndpoint == null || this.openviduWebhookEndpoint.isEmpty()) {
|
|
||||||
log.error(
|
|
||||||
"If OpenVidu Webhook service is enabled property 'openvidu.webhook.endpoint' must be defined");
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
this.initiateOpenViduWebhookEndpoint(this.openviduWebhookEndpoint);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error in 'openvidu.webhook.endpoint' system property. " + e.getMessage());
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.initiateOpenViduWebhookHeaders(this.openviduWebhookHeaders);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error in 'openvidu.webhook.headers' system property: " + e.getMessage());
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.initiateOpenViduWebhookEvents(this.openviduWebhookEvents);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error in 'openvidu.webhook.events' system property: " + e.getMessage());
|
|
||||||
log.error("Shutting down OpenVidu Server");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getKmsUris() {
|
public List<String> getKmsUris() {
|
||||||
return this.kmsUrisList;
|
return this.kmsUrisList;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +278,7 @@ public class OpenviduConfig {
|
||||||
return this.coturnRedisDbname;
|
return this.coturnRedisDbname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOpenViduRecordingNotification() {
|
public RecordingNotification getOpenViduRecordingNotification() {
|
||||||
return this.openviduRecordingNotification;
|
return this.openviduRecordingNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,16 +305,16 @@ public class OpenviduConfig {
|
||||||
public OpenViduRole[] getRolesFromRecordingNotification() {
|
public OpenViduRole[] getRolesFromRecordingNotification() {
|
||||||
OpenViduRole[] roles;
|
OpenViduRole[] roles;
|
||||||
switch (this.openviduRecordingNotification) {
|
switch (this.openviduRecordingNotification) {
|
||||||
case "none":
|
case none:
|
||||||
roles = new OpenViduRole[0];
|
roles = new OpenViduRole[0];
|
||||||
break;
|
break;
|
||||||
case "moderator":
|
case moderator:
|
||||||
roles = new OpenViduRole[] { OpenViduRole.MODERATOR };
|
roles = new OpenViduRole[] { OpenViduRole.MODERATOR };
|
||||||
break;
|
break;
|
||||||
case "publisher_moderator":
|
case publisher_moderator:
|
||||||
roles = new OpenViduRole[] { OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
roles = new OpenViduRole[] { OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
||||||
break;
|
break;
|
||||||
case "all":
|
case all:
|
||||||
roles = new OpenViduRole[] { OpenViduRole.SUBSCRIBER, OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
roles = new OpenViduRole[] { OpenViduRole.SUBSCRIBER, OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -380,6 +347,256 @@ public class OpenviduConfig {
|
||||||
return this.externalizedProperties;
|
return this.externalizedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkWebsocketUri(String uri) throws Exception {
|
||||||
|
try {
|
||||||
|
if (!uri.startsWith("ws://") || uri.startsWith("wss://")) {
|
||||||
|
throw new Exception("WebSocket protocol not found");
|
||||||
|
}
|
||||||
|
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
|
||||||
|
new URL(parsedUri).toURI();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("URI '" + uri + "' has not a valid WebSocket endpoint format: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkConfigurationParameters(Map<String, ?> parameters, Collection<String> validKeys) throws Exception {
|
||||||
|
|
||||||
|
parameters = this.filterValidParameters(parameters, validKeys);
|
||||||
|
|
||||||
|
log.info("Checking configuration parameters: {}", parameters.keySet());
|
||||||
|
|
||||||
|
for (String parameter : parameters.keySet()) {
|
||||||
|
switch (parameter) {
|
||||||
|
case "openvidu.secret":
|
||||||
|
String secret = checkString(parameters, parameter);
|
||||||
|
if (secret.isEmpty()) {
|
||||||
|
throw new Exception("Property 'openvidu.secret' cannot be empty");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.publicurl":
|
||||||
|
String publicurl = checkString(parameters, parameter);
|
||||||
|
if (!OPENVIDU_VALID_PUBLICURL_VALUES.contains(publicurl)) {
|
||||||
|
// Must be a valid URL
|
||||||
|
try {
|
||||||
|
new URL(publicurl).toURI();
|
||||||
|
} catch (MalformedURLException | URISyntaxException e) {
|
||||||
|
throw new Exception(
|
||||||
|
"Property 'openvidu.publicurl' has not a valid URL format: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.cdr":
|
||||||
|
checkBoolean(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.recording":
|
||||||
|
checkBoolean(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.recording.public-access":
|
||||||
|
checkBoolean(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.recording.autostop-timeout":
|
||||||
|
checkIntegerNonNegative(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.recording.notification":
|
||||||
|
String recordingNotif = checkString(parameters, parameter);
|
||||||
|
try {
|
||||||
|
RecordingNotification.valueOf(recordingNotif);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new Exception("Property 'openvidu.recording.notification' has not a valid value ('"
|
||||||
|
+ recordingNotif + "'). Must be one of " + Arrays.asList(RecordingNotification.values()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.webhook":
|
||||||
|
checkBoolean(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.webhook.endpoint":
|
||||||
|
String webhookEndpoint = checkString(parameters, parameter);
|
||||||
|
try {
|
||||||
|
checkWebhookEndpoint(webhookEndpoint);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Property 'openvidu.webhook.endpoint' is not valid: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.streams.video.max-recv-bandwidth":
|
||||||
|
checkIntegerNonNegative(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.streams.video.min-recv-bandwidth":
|
||||||
|
checkIntegerNonNegative(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.streams.video.max-send-bandwidth":
|
||||||
|
checkIntegerNonNegative(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.streams.video.min-send-bandwidth":
|
||||||
|
checkIntegerNonNegative(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "kms.uris":
|
||||||
|
String kmsUris;
|
||||||
|
try {
|
||||||
|
// First check if castable to a List
|
||||||
|
List<?> list = checkArray(parameters, parameter);
|
||||||
|
String elementString;
|
||||||
|
for (Object element : list) {
|
||||||
|
try {
|
||||||
|
// Check every object is a String value
|
||||||
|
elementString = (String) element;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property 'kms.uris' is an array, but contains a value (" + element
|
||||||
|
+ ") that is not a string: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kmsUris = list.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If it is not a list, try casting to String
|
||||||
|
kmsUris = checkString(parameters, parameter);
|
||||||
|
}
|
||||||
|
// Finally check all strings have a valid WebSocket URI format
|
||||||
|
try {
|
||||||
|
kmsUrisStringToList(kmsUris);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception(
|
||||||
|
"Property 'kms.uris' is an array of strings, but contains some value that has not a valid WbeSocket URI format: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.webhook.headers":
|
||||||
|
String webhookHeaders;
|
||||||
|
try {
|
||||||
|
// First check if castable to a List
|
||||||
|
List<?> list = checkArray(parameters, parameter);
|
||||||
|
String elementString;
|
||||||
|
for (Object element : list) {
|
||||||
|
try {
|
||||||
|
// Check every object is a String value
|
||||||
|
elementString = (String) element;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception(
|
||||||
|
"Property 'openvidu.webhook.headers' is an array, but contains a value (" + element
|
||||||
|
+ ") that is not a string: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webhookHeaders = list.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If it is not a list, try casting to String
|
||||||
|
webhookHeaders = checkString(parameters, parameter);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
checkWebhookHeaders(webhookHeaders);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception(
|
||||||
|
"Property 'openvidu.webhook.headers' contains a value not valid: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.webhook.events":
|
||||||
|
String webhookEvents;
|
||||||
|
try {
|
||||||
|
// First check if castable to a List
|
||||||
|
List<?> list = checkArray(parameters, parameter);
|
||||||
|
String elementString;
|
||||||
|
for (Object element : list) {
|
||||||
|
try {
|
||||||
|
// Check every object is a String value
|
||||||
|
elementString = (String) element;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property 'openvidu.webhook.events' is an array, but contains a value ("
|
||||||
|
+ element + ") that is not a string: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webhookEvents = list.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If it is not a list, try casting to String
|
||||||
|
webhookEvents = checkString(parameters, parameter);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
checkWebhookEvents(webhookEvents);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception(
|
||||||
|
"Property 'openvidu.webhook.events' contains a value not valid: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openvidu.recording.path":
|
||||||
|
checkString(parameters, parameter);
|
||||||
|
break;
|
||||||
|
case "openvidu.recording.custom-layout":
|
||||||
|
checkString(parameters, parameter);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("Unknown configuration parameter '{}'", parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String checkString(Map<String, ?> parameters, String key) throws Exception {
|
||||||
|
try {
|
||||||
|
String stringValue = (String) parameters.get(key);
|
||||||
|
return stringValue;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property '" + key + "' must be a string: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkBoolean(Map<String, ?> parameters, String key) throws Exception {
|
||||||
|
try {
|
||||||
|
boolean booleanValue = Boolean.parseBoolean((String) parameters.get(key));
|
||||||
|
return booleanValue;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property '" + key + "' must be a boolean: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer checkIntegerNonNegative(Map<String, ?> parameters, String key) throws Exception {
|
||||||
|
try {
|
||||||
|
Integer integerValue = Integer.parseInt((String) parameters.get(key));
|
||||||
|
if (integerValue < 0) {
|
||||||
|
throw new Exception("Property '" + key + "' is an integer but cannot be less than 0 (current value: "
|
||||||
|
+ integerValue + ")");
|
||||||
|
}
|
||||||
|
return integerValue;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property '" + key + "' must be an integer: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> checkArray(Map<String, ?> parameters, String key) throws Exception {
|
||||||
|
try {
|
||||||
|
List<String> list = (List<String>) parameters.get(key);
|
||||||
|
return list;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new Exception("Property '" + key + "' must be an array: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ?> filterValidParameters(Map<String, ?> parameters, Collection<String> validKeys) {
|
||||||
|
return parameters.entrySet().stream().filter(x -> validKeys.contains(x.getKey()))
|
||||||
|
.collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Properties retrieveExternalizedProperties() throws Exception {
|
||||||
|
|
||||||
|
if (this.springConfigLocation.isEmpty()) {
|
||||||
|
throw new Exception(
|
||||||
|
"Externalized properties file not found. Path must be set with configuration parameter 'spring.config.additional-location'");
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties externalizedProps = null;
|
||||||
|
FileSystemResource resource = new FileSystemResource(this.springConfigLocation);
|
||||||
|
try {
|
||||||
|
externalizedProps = PropertiesLoaderUtils.loadProperties(resource);
|
||||||
|
log.info("Properties file found at \"{}\". Content: {}", this.springConfigLocation, externalizedProps);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Exception("Error in 'spring.config.additional-location' system property. Cannot load properties: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
// Check OpenVidu Server write permissions in properties path
|
||||||
|
if (!Files.isWritable(Paths.get(this.springConfigLocation))) {
|
||||||
|
log.warn(
|
||||||
|
"The properties path '{}' set with property 'spring.config.additional-location' is missconfigured. Reason: OpenVidu Server needs write permissions. Try running command \"sudo chmod 777 {}\". If not, OpenVidu won't be able to overwrite preexisting properties",
|
||||||
|
this.springConfigLocation, this.springConfigLocation);
|
||||||
|
} else {
|
||||||
|
log.info("OpenVidu Server has write permissions on properties path {}", this.springConfigLocation);
|
||||||
|
}
|
||||||
|
return externalizedProps;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> kmsUrisStringToList(String kmsUris) throws Exception {
|
public List<String> kmsUrisStringToList(String kmsUris) throws Exception {
|
||||||
kmsUris = kmsUris.replaceAll("\\s", ""); // Remove all white spaces
|
kmsUris = kmsUris.replaceAll("\\s", ""); // Remove all white spaces
|
||||||
kmsUris = kmsUris.replaceAll("\\\\", ""); // Remove previous escapes
|
kmsUris = kmsUris.replaceAll("\\\\", ""); // Remove previous escapes
|
||||||
|
@ -392,7 +609,6 @@ public class OpenviduConfig {
|
||||||
|
|
||||||
List<String> list = JsonUtils.toStringList(kmsUrisArray);
|
List<String> list = JsonUtils.toStringList(kmsUrisArray);
|
||||||
if (list.size() == 1 && list.get(0).isEmpty()) {
|
if (list.size() == 1 && list.get(0).isEmpty()) {
|
||||||
log.warn("Array kms.uris is empty");
|
|
||||||
list = new ArrayList<>();
|
list = new ArrayList<>();
|
||||||
} else {
|
} else {
|
||||||
for (String uri : list) {
|
for (String uri : list) {
|
||||||
|
@ -402,20 +618,20 @@ public class OpenviduConfig {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initiateOpenViduWebhookEndpoint(String endpoint) throws Exception {
|
private void checkWebhookEndpoint(String endpoint) throws Exception {
|
||||||
try {
|
try {
|
||||||
new URL(endpoint);
|
new URL(endpoint).toURI();
|
||||||
log.info("OpenVidu Webhook endpoint is {}", endpoint);
|
log.info("OpenVidu Webhook endpoint is {}", endpoint);
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException | URISyntaxException e) {
|
||||||
throw new Exception("Webhook endpoint '" + endpoint + "' is not correct. Malformed URL: " + e.getMessage());
|
throw new Exception("Webhook endpoint '" + endpoint + "' is not correct. Malformed URL: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initiateOpenViduWebhookHeaders(String headers) throws Exception {
|
private List<Header> checkWebhookHeaders(String headers) throws Exception {
|
||||||
JsonParser parser = new JsonParser();
|
JsonParser parser = new JsonParser();
|
||||||
JsonElement elem = parser.parse(headers);
|
JsonElement elem = parser.parse(headers);
|
||||||
JsonArray headersJsonArray = elem.getAsJsonArray();
|
JsonArray headersJsonArray = elem.getAsJsonArray();
|
||||||
this.webhookHeadersList = new ArrayList<>();
|
List<Header> headerList = new ArrayList<>();
|
||||||
|
|
||||||
for (JsonElement jsonElement : headersJsonArray) {
|
for (JsonElement jsonElement : headersJsonArray) {
|
||||||
String headerString = jsonElement.getAsString();
|
String headerString = jsonElement.getAsString();
|
||||||
|
@ -434,37 +650,112 @@ public class OpenviduConfig {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
"HTTP header '" + headerString + "' syntax is not correct. Header value cannot be empty");
|
"HTTP header '" + headerString + "' syntax is not correct. Header value cannot be empty");
|
||||||
}
|
}
|
||||||
this.webhookHeadersList.add(new BasicHeader(headerName, headerValue));
|
headerList.add(new BasicHeader(headerName, headerValue));
|
||||||
}
|
}
|
||||||
log.info("OpenVidu Webhook headers: {}", this.getOpenViduWebhookHeaders().toString());
|
return headerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initiateOpenViduWebhookEvents(String events) throws Exception {
|
private List<CDREventName> checkWebhookEvents(String events) throws Exception {
|
||||||
JsonParser parser = new JsonParser();
|
JsonParser parser = new JsonParser();
|
||||||
JsonElement elem = parser.parse(events);
|
JsonElement elem = parser.parse(events);
|
||||||
JsonArray eventsJsonArray = elem.getAsJsonArray();
|
JsonArray eventsJsonArray = elem.getAsJsonArray();
|
||||||
this.webhookEventsList = new ArrayList<>();
|
List<CDREventName> eventList = new ArrayList<>();
|
||||||
|
|
||||||
for (JsonElement jsonElement : eventsJsonArray) {
|
for (JsonElement jsonElement : eventsJsonArray) {
|
||||||
String eventString = jsonElement.getAsString();
|
String eventString = jsonElement.getAsString();
|
||||||
try {
|
try {
|
||||||
CDREventName.valueOf(eventString);
|
CDREventName.valueOf(eventString);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new Exception("Event name '" + eventString + "' does not exist");
|
throw new Exception("Event '" + eventString + "' does not exist");
|
||||||
}
|
}
|
||||||
this.webhookEventsList.add(CDREventName.valueOf(eventString));
|
eventList.add(CDREventName.valueOf(eventString));
|
||||||
}
|
}
|
||||||
log.info("OpenVidu Webhook events: {}", this.getOpenViduWebhookEvents().toString());
|
return eventList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkWebsocketUri(String uri) throws MalformedURLException {
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
|
||||||
|
// Check configuration parameters
|
||||||
|
Map<String, ?> props = null;
|
||||||
|
if (!this.springConfigLocation.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
|
this.externalizedProperties = this.retrieveExternalizedProperties();
|
||||||
new URL(parsedUri);
|
props = (Map) this.externalizedProperties;
|
||||||
} catch (MalformedURLException e) {
|
} catch (Exception e) {
|
||||||
log.error("URI {} is not a valid WebSocket endpoint", uri);
|
log.error(e.getMessage());
|
||||||
throw e;
|
log.error("Shutting down OpenVidu Server");
|
||||||
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
props = (Map) System.getProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.checkConfigurationParameters(props, OPENVIDU_PROPERTIES);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error("Shutting down OpenVidu Server");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.kmsUrisList = this.kmsUrisStringToList(this.kmsUris);
|
||||||
|
if (this.isWebhookEnabled()) {
|
||||||
|
this.webhookHeadersList = this.checkWebhookHeaders(this.openviduWebhookHeaders);
|
||||||
|
this.webhookEventsList = this.checkWebhookEvents(this.openviduWebhookEvents);
|
||||||
|
log.info("OpenVidu Webhook endpoint: {}", this.openviduWebhookEndpoint);
|
||||||
|
log.info("OpenVidu Webhook headers: {}", this.getOpenViduWebhookHeaders().toString());
|
||||||
|
log.info("OpenVidu Webhook events: {}", this.getOpenViduWebhookEvents().toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Unexpected exception when setting final value of configuration parameters: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate final public url
|
||||||
|
String publicUrl = this.getOpenViduPublicUrl();
|
||||||
|
String type = "";
|
||||||
|
switch (publicUrl) {
|
||||||
|
case "docker":
|
||||||
|
try {
|
||||||
|
String containerIp = OpenViduServer.getContainerIp();
|
||||||
|
OpenViduServer.wsUrl = "wss://" + containerIp + ":" + this.getServerPort();
|
||||||
|
} catch (Exception e) {
|
||||||
|
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 (!OpenViduServer.wsUrl.startsWith("wss://")) {
|
||||||
|
OpenViduServer.wsUrl = "wss://" + OpenViduServer.wsUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpenViduServer.wsUrl == null) {
|
||||||
|
type = "local";
|
||||||
|
OpenViduServer.wsUrl = "wss://localhost:" + this.getServerPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpenViduServer.wsUrl.endsWith("/")) {
|
||||||
|
OpenViduServer.wsUrl = OpenViduServer.wsUrl.substring(0, OpenViduServer.wsUrl.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String finalUrl = OpenViduServer.wsUrl.replaceFirst("wss://", "https://").replaceFirst("ws://", "http://");
|
||||||
|
this.setFinalUrl(finalUrl);
|
||||||
|
OpenViduServer.httpUrl = this.getFinalUrl();
|
||||||
|
OpenViduServer.publicurlType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package io.openvidu.server.recording;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines which users should receive the Session recording notifications on the
|
||||||
|
* client side (recordingStarted, recordingStopped)
|
||||||
|
*
|
||||||
|
* @author Pablo Fuente (pablofuenteperez@gmail.com)
|
||||||
|
*/
|
||||||
|
public enum RecordingNotification {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No user of the session will receive recording events
|
||||||
|
*/
|
||||||
|
none,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only users with role MODERATOR will receive recording events
|
||||||
|
*/
|
||||||
|
moderator,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Users with role MODERATOR or PUBLISHER will receive recording events
|
||||||
|
*/
|
||||||
|
publisher_moderator,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All users of to the session will receive recording events
|
||||||
|
*/
|
||||||
|
all
|
||||||
|
|
||||||
|
}
|
|
@ -36,6 +36,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.kurento.client.ErrorEvent;
|
import org.kurento.client.ErrorEvent;
|
||||||
import org.kurento.client.EventListener;
|
import org.kurento.client.EventListener;
|
||||||
|
@ -116,6 +118,30 @@ public class RecordingManager {
|
||||||
.asList(new EndReason[] { EndReason.disconnect, EndReason.forceDisconnectByUser,
|
.asList(new EndReason[] { EndReason.disconnect, EndReason.forceDisconnectByUser,
|
||||||
EndReason.forceDisconnectByServer, EndReason.networkDisconnect });
|
EndReason.forceDisconnectByServer, EndReason.networkDisconnect });
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
if (this.openviduConfig.isRecordingModuleEnabled()) {
|
||||||
|
try {
|
||||||
|
this.initializeRecordingManager();
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
String finalErrorMessage = "";
|
||||||
|
if (e.getCodeValue() == Code.DOCKER_NOT_FOUND.getValue()) {
|
||||||
|
finalErrorMessage = "Error connecting to Docker daemon. Enabling OpenVidu recording module requires Docker";
|
||||||
|
} else if (e.getCodeValue() == Code.RECORDING_PATH_NOT_VALID.getValue()) {
|
||||||
|
finalErrorMessage = "Error initializing recording path \""
|
||||||
|
+ this.openviduConfig.getOpenViduRecordingPath()
|
||||||
|
+ "\" set with system property \"openvidu.recording.path\"";
|
||||||
|
} else if (e.getCodeValue() == Code.RECORDING_FILE_EMPTY_ERROR.getValue()) {
|
||||||
|
finalErrorMessage = "Error initializing recording custom layouts path \""
|
||||||
|
+ this.openviduConfig.getOpenviduRecordingCustomLayout()
|
||||||
|
+ "\" set with system property \"openvidu.recording.custom-layout\"";
|
||||||
|
}
|
||||||
|
log.error(finalErrorMessage + ". Shutting down OpenVidu Server");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void initializeRecordingManager() throws OpenViduException {
|
public void initializeRecordingManager() throws OpenViduException {
|
||||||
|
|
||||||
RecordingManager.IMAGE_TAG = openviduConfig.getOpenViduRecordingVersion();
|
RecordingManager.IMAGE_TAG = openviduConfig.getOpenViduRecordingVersion();
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class ConfigRestController {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ConfigRestController.class);
|
private static final Logger log = LoggerFactory.getLogger(ConfigRestController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected OpenviduConfig openviduConfig;
|
private OpenviduConfig openviduConfig;
|
||||||
|
|
||||||
@RequestMapping(value = "/openvidu-version", method = RequestMethod.GET)
|
@RequestMapping(value = "/openvidu-version", method = RequestMethod.GET)
|
||||||
public String getOpenViduServerVersion() {
|
public String getOpenViduServerVersion() {
|
||||||
|
@ -108,7 +108,7 @@ public class ConfigRestController {
|
||||||
json.addProperty("openviduRecordingVersion", openviduConfig.getOpenViduRecordingVersion());
|
json.addProperty("openviduRecordingVersion", openviduConfig.getOpenViduRecordingVersion());
|
||||||
json.addProperty("openviduRecordingPath", openviduConfig.getOpenViduRecordingPath());
|
json.addProperty("openviduRecordingPath", openviduConfig.getOpenViduRecordingPath());
|
||||||
json.addProperty("openviduRecordingPublicAccess", openviduConfig.getOpenViduRecordingPublicAccess());
|
json.addProperty("openviduRecordingPublicAccess", openviduConfig.getOpenViduRecordingPublicAccess());
|
||||||
json.addProperty("openviduRecordingNotification", openviduConfig.getOpenViduRecordingNotification());
|
json.addProperty("openviduRecordingNotification", openviduConfig.getOpenViduRecordingNotification().name());
|
||||||
json.addProperty("openviduRecordingCustomLayout", openviduConfig.getOpenviduRecordingCustomLayout());
|
json.addProperty("openviduRecordingCustomLayout", openviduConfig.getOpenviduRecordingCustomLayout());
|
||||||
json.addProperty("openviduRecordingAutostopTimeout", openviduConfig.getOpenviduRecordingAutostopTimeout());
|
json.addProperty("openviduRecordingAutostopTimeout", openviduConfig.getOpenviduRecordingAutostopTimeout());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue