Skip to content

Commit 4a0e096

Browse files
committed
[native] Add support for env vars providing property values
This allows a user to configure the value of an environment variable to be used as value for a configuration property. For example, the configuration file may contain keys that would be hard coded. The values can now be replaced by environment variables that are read at startup time and the keys don't require hard coding in the configuration file.
1 parent c8a90e5 commit 4a0e096

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

presto-native-execution/presto_cpp/main/common/ConfigReader.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,25 @@
1919
#include "velox/common/config/Config.h"
2020

2121
namespace facebook::presto::util {
22+
23+
namespace {
24+
// Replaces strings of the form "${VAR}"
25+
// with the value of the environment variable "VAR" (if it exists).
26+
// Does nothing if the input doesn't look like "${...}".
27+
std::string replaceIfEnvironmentVariable(std::string_view str) {
28+
if (str.size() >= 3 && str.substr(0, 2) == "${" &&
29+
str[str.size() - 1] == '}') {
30+
auto env_name = std::string(str.substr(2, str.size() - 3));
31+
32+
char* envval = std::getenv(env_name.c_str());
33+
if (envval) {
34+
return std::string(envval);
35+
}
36+
}
37+
return std::string(str);
38+
}
39+
} // namespace
40+
2241
std::unordered_map<std::string, std::string> readConfig(
2342
const std::string& filePath) {
2443
// https://teradata.github.io/presto/docs/141t/configuration/configuration.html
@@ -45,7 +64,8 @@ std::unordered_map<std::string, std::string> readConfig(
4564
const auto name = line.substr(0, delimiterPos);
4665
VELOX_CHECK(!name.empty(), "property pair '{}' has empty key", line);
4766
const auto value = line.substr(delimiterPos + 1);
48-
properties.emplace(name, value);
67+
const auto adjustedValue = replaceIfEnvironmentVariable(value);
68+
properties.emplace(name, adjustedValue);
4969
}
5070

5171
return properties;

presto-native-execution/presto_cpp/main/common/tests/ConfigTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,33 @@ TEST_F(ConfigTest, optionalNodeId) {
255255
EXPECT_EQ(nodeId, config.nodeId());
256256
}
257257

258+
TEST_F(ConfigTest, readConfigEnvVarTest) {
259+
char path[] = "/tmp/velox_system_config_test_XXXXXX";
260+
const char* tempDirectoryPath = mkdtemp(path);
261+
if (tempDirectoryPath == nullptr) {
262+
throw std::logic_error("Cannot open temp directory");
263+
}
264+
265+
std::string propFilePath = tempDirectoryPath;
266+
propFilePath += "/envtest.properties";
267+
std::string ENV_VAR = "PRESTO_READ_CONFIG_TEST_VAR";
268+
269+
std::ofstream propFile (propFilePath);
270+
propFile << fmt::format("{}={}\n", "plain-text", "plain-text-value");
271+
propFile << fmt::format("{}=${{{}}}\n", "env-var", ENV_VAR);
272+
propFile << fmt::format("{}=${{{}\n", "env-var2", ENV_VAR);
273+
propFile << fmt::format("{}={}}}\n", "env-var3", ENV_VAR);
274+
propFile << fmt::format("{}=${{}}\n", "no-env-var");
275+
propFile.close();
276+
277+
setenv(ENV_VAR.c_str(), "env-var-value", 1);
278+
auto properties = facebook::presto::util::readConfig(propFilePath);
279+
ASSERT_EQ(properties["plain-text"], "plain-text-value");
280+
ASSERT_EQ(properties["env-var"], "env-var-value");
281+
ASSERT_EQ(properties["env-var2"], "${PRESTO_READ_CONFIG_TEST_VAR");
282+
ASSERT_EQ(properties["env-var3"], "PRESTO_READ_CONFIG_TEST_VAR}");
283+
ASSERT_EQ(properties["no-env-var"], "${}");
284+
unsetenv(ENV_VAR.c_str());
285+
}
286+
258287
} // namespace facebook::presto::test

0 commit comments

Comments
 (0)