diff --git a/openvidu-server/src/main/java/io/openvidu/server/config/Dotenv.java b/openvidu-server/src/main/java/io/openvidu/server/config/Dotenv.java index b5ff822a..b150b0a7 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/config/Dotenv.java +++ b/openvidu-server/src/main/java/io/openvidu/server/config/Dotenv.java @@ -44,6 +44,10 @@ public class Dotenv { return properties.get(property); } + public Map getAll() { + return properties; + } + public Path getEnvFile() { return envFile; } @@ -55,26 +59,25 @@ public class Dotenv { public void write(Path envFile) throws IOException { List outLines = new ArrayList<>(); - + + int lineNumber = 1; for (String line : lines) { - try { - - Pair propValue = parseLine(envFile, line); - if(propValue == null) { + Pair propValue = parseLine(envFile, line, lineNumber); + if (propValue == null) { outLines.add(line); } else { - outLines.add(propValue.getKey()+"="+properties.get(propValue.getKey())); + outLines.add(propValue.getKey() + "=" + properties.get(propValue.getKey())); } - } catch (DotenvFormatException e) { log.error("Previously parsed line is producing a parser error", e); } + lineNumber++; } - - if(!additionalProperties.isEmpty()) { - for(String prop : additionalProperties) { - outLines.add(prop+"="+properties.get(prop)); + + if (!additionalProperties.isEmpty()) { + for (String prop : additionalProperties) { + outLines.add(prop + "=" + properties.get(prop)); } } @@ -88,12 +91,13 @@ public class Dotenv { lines = Files.readAllLines(envFile); + int lineNumber = 1; properties = new HashMap<>(); for (String line : lines) { log.debug("Reading line '{}'", line); - Pair propValue = parseLine(envFile, line); + Pair propValue = parseLine(envFile, line, lineNumber); if (propValue != null) { @@ -101,10 +105,12 @@ public class Dotenv { properties.put(propValue.getKey(), propValue.getValue()); } + + lineNumber++; } } - private Pair parseLine(Path envFile, String line) throws DotenvFormatException { + private Pair parseLine(Path envFile, String line, int lineNumber) throws DotenvFormatException { if (isWhitespace(line) || isComment(line)) { return null; @@ -113,13 +119,15 @@ public class Dotenv { int index = line.indexOf("="); if (index == -1) { - throw new DotenvFormatException("File " + envFile + " has a malformed line with content \"" + line + "\""); + throw new DotenvFormatException("File " + envFile + " has a malformed line at position " + lineNumber + + " with content \"" + line + "\""); } String property = line.substring(0, index).trim(); if (property.equals("")) { - throw new DotenvFormatException("File " + envFile + " has a malformed line with content \"" + line + "\""); + throw new DotenvFormatException("File " + envFile + " has a malformed line at position " + lineNumber + + " with content \"" + line + "\""); } String value = line.substring(index + 1); diff --git a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java index ee90d7bf..92cd0f6d 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java +++ b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java @@ -18,6 +18,7 @@ package io.openvidu.server.config; import java.io.File; +import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -52,6 +53,7 @@ import com.google.gson.JsonSyntaxException; import io.openvidu.java.client.OpenViduRole; import io.openvidu.server.OpenViduServer; import io.openvidu.server.cdr.CDREventName; +import io.openvidu.server.config.Dotenv.DotenvFormatException; import io.openvidu.server.recording.RecordingNotification; @Component @@ -421,29 +423,35 @@ public class OpenviduConfig { this.configErrors.add(new Error(property, value, msg)); } - @PostConstruct - public void checkConfiguration() { - + public void checkConfiguration(boolean loadDotenv) { try { - this.checkConfigurationProperties(); + this.checkConfigurationProperties(loadDotenv); } catch (Exception e) { log.error("Exception checking configuration", e); addError(null, "Exception checking configuration." + e.getClass().getName() + ":" + e.getMessage()); } - userConfigProps = new ArrayList<>(configProps.keySet()); - userConfigProps.removeAll(getNonUserProperties()); } + @PostConstruct + public void checkConfiguration() { + this.checkConfiguration(true); + } + protected List getNonUserProperties() { - return Arrays.asList("server.port", "COTURN_IP", "COTURN_REDIS_IP", "KMS_URIS", "COTURN_REDIS_DBNAME", - "COTURN_REDIS_PASSWORD", "COTURN_REDIS_CONNECT_TIMEOUT"); + return Arrays.asList("server.port", "DOTENV_PATH", "COTURN_IP", "COTURN_REDIS_IP", "KMS_URIS", + "COTURN_REDIS_DBNAME", "COTURN_REDIS_PASSWORD", "COTURN_REDIS_CONNECT_TIMEOUT"); } // Properties - protected void checkConfigurationProperties() { + protected void checkConfigurationProperties(boolean loadDotenv) { + + if (loadDotenv) { + dotenvPath = getValue("DOTENV_PATH"); + this.populatePropertySourceFromDotenv(); + } serverPort = getValue("server.port"); @@ -489,7 +497,6 @@ public class OpenviduConfig { checkCertificateType(); - dotenvPath = getValue("DOTENV_PATH"); } private void checkCertificateType() { @@ -860,4 +867,51 @@ public class OpenviduConfig { } } + protected void populatePropertySourceFromDotenv() { + File dotenvFile = this.getDotenvFile(); + if (dotenvFile != null) { + if (dotenvFile.canRead()) { + Dotenv dotenv = new Dotenv(); + try { + dotenv.read(dotenvFile.toPath()); + this.propertiesSource = dotenv.getAll(); + log.info("Configuration properties read from file {}", dotenvFile.getAbsolutePath()); + } catch (IOException | DotenvFormatException e) { + log.error("Error reading properties from .env file: {}", e.getMessage()); + addError(null, e.getMessage()); + } + } else { + log.error("OpenVidu does not have read permissions over .env file at {}", this.getDotenvPath()); + } + } + } + + public File getDotenvFile() { + if (this.getDotenvPath() != null && !this.getDotenvPath().isEmpty()) { + File file = new File(this.getDotenvPath()); + if (file.exists()) { + if (file.isDirectory()) { + file = new File(file, ".env"); + if (file.exists() && file.isFile()) { + return file; + } else { + log.error(".env file not found at folder {}", this.getDotenvPath()); + } + } else { + if (".env".equals(file.getName())) { + return file; + } else { + log.error("DOTEN_PATH configuration property refers to a file which is not .env ({})", + this.getDotenvPath()); + } + } + } else { + log.error(".env file not found at {}", this.getDotenvPath()); + } + } else { + log.warn("DOTENV_PATH configuration property is not defined"); + } + return null; + } + } \ No newline at end of file