Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2023 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "ConfigHelper.h"
21 : #include "IConfigReader.h"
22 : #include "RialtoServerManagerLogging.h"
23 : #include <list>
24 : #include <map>
25 : #include <memory>
26 :
27 : namespace
28 : {
29 59 : std::map<std::string, std::string> convertToMap(const std::list<std::string> &envVariablesList)
30 : {
31 59 : std::map<std::string, std::string> result{};
32 102 : for (const auto &var : envVariablesList)
33 : {
34 43 : const auto kSplitPos{var.find("=")};
35 43 : if (std::string::npos == kSplitPos || kSplitPos + 1 >= var.size())
36 : {
37 0 : continue;
38 : }
39 43 : std::string name = var.substr(0, kSplitPos);
40 43 : std::string value = var.substr(kSplitPos + 1);
41 43 : result.emplace(name, value);
42 : }
43 59 : return result;
44 : }
45 :
46 13 : std::list<std::string> convertToList(const std::map<std::string, std::string> &envVariablesMap)
47 : {
48 13 : std::list<std::string> result{};
49 29 : for (const auto &[name, value] : envVariablesMap)
50 : {
51 16 : result.emplace_back(name + "=" + value);
52 : }
53 13 : return result;
54 : }
55 : } // namespace
56 :
57 : namespace rialto::servermanager::service
58 : {
59 13 : ConfigHelper::ConfigHelper(std::unique_ptr<IConfigReaderFactory> &&configReaderFactory,
60 13 : const firebolt::rialto::common::ServerManagerConfig &config)
61 13 : : m_configReaderFactory{std::move(configReaderFactory)}, m_sessionServerEnvVars{convertToMap(
62 13 : config.sessionServerEnvVars)},
63 13 : m_sessionServerPath{config.sessionServerPath}, m_sessionServerStartupTimeout{config.sessionServerStartupTimeout},
64 13 : m_healthcheckInterval{config.healthcheckInterval}, m_socketPermissions{config.sessionManagementSocketPermissions},
65 13 : m_numOfPreloadedServers{config.numOfPreloadedServers},
66 13 : m_numOfFailedPingsBeforeRecovery{config.numOfFailedPingsBeforeRecovery}, m_loggingLevels{}
67 : {
68 : #ifdef RIALTO_ENABLE_CONFIG_FILE
69 : // Read from least to most important file
70 13 : readConfigFile(RIALTO_CONFIG_PATH);
71 13 : readConfigFile(RIALTO_CONFIG_SOC_PATH);
72 13 : readConfigFile(RIALTO_CONFIG_OVERRIDES_PATH);
73 13 : mergeEnvVariables();
74 : #endif // RIALTO_ENABLE_CONFIG_FILE
75 : }
76 :
77 13 : std::list<std::string> ConfigHelper::getSessionServerEnvVars() const
78 : {
79 13 : return convertToList(m_sessionServerEnvVars);
80 : }
81 :
82 13 : const std::string &ConfigHelper::getSessionServerPath() const
83 : {
84 13 : return m_sessionServerPath;
85 : }
86 :
87 13 : std::chrono::milliseconds ConfigHelper::getSessionServerStartupTimeout() const
88 : {
89 13 : return m_sessionServerStartupTimeout;
90 : }
91 :
92 13 : std::chrono::seconds ConfigHelper::getHealthcheckInterval() const
93 : {
94 13 : return m_healthcheckInterval;
95 : }
96 :
97 65 : firebolt::rialto::common::SocketPermissions ConfigHelper::getSocketPermissions() const
98 : {
99 65 : return m_socketPermissions;
100 : }
101 :
102 13 : unsigned int ConfigHelper::getNumOfPreloadedServers() const
103 : {
104 13 : return m_numOfPreloadedServers;
105 : }
106 :
107 13 : unsigned int ConfigHelper::getNumOfFailedPingsBeforeRecovery() const
108 : {
109 13 : return m_numOfFailedPingsBeforeRecovery;
110 : }
111 :
112 78 : const rialto::servermanager::service::LoggingLevels &ConfigHelper::getLoggingLevels() const
113 : {
114 78 : return m_loggingLevels;
115 : }
116 :
117 : #ifdef RIALTO_ENABLE_CONFIG_FILE
118 39 : void ConfigHelper::readConfigFile(const std::string &filePath)
119 : {
120 39 : if (!m_configReaderFactory)
121 : {
122 3 : RIALTO_SERVER_MANAGER_LOG_DEBUG("Config reader factory not present");
123 16 : return;
124 : }
125 36 : std::shared_ptr<IConfigReader> configReader = m_configReaderFactory->createConfigReader(filePath);
126 36 : if (!configReader || !configReader->read())
127 : {
128 13 : RIALTO_SERVER_MANAGER_LOG_DEBUG("Config file not present: %s", filePath.c_str());
129 13 : return;
130 : }
131 :
132 : // Always override env variables when present in "more important" file
133 : // (envVariables + extraEnvVariables from less important file will be wiped if envVariables are present)
134 23 : const std::map<std::string, std::string> envVariables{convertToMap(configReader->getEnvironmentVariables())};
135 23 : if (!envVariables.empty())
136 : {
137 17 : m_envVarsFromConfigFile = envVariables;
138 17 : m_extraEnvVarsFromConfigFile.clear();
139 : }
140 23 : const std::map<std::string, std::string> extraEnvVariables{convertToMap(configReader->getExtraEnvVariables())};
141 23 : if (!extraEnvVariables.empty())
142 : {
143 13 : m_extraEnvVarsFromConfigFile = extraEnvVariables;
144 : }
145 :
146 23 : if (configReader->getSessionServerPath())
147 5 : m_sessionServerPath = configReader->getSessionServerPath().value();
148 :
149 23 : if (configReader->getSessionServerStartupTimeout())
150 5 : m_sessionServerStartupTimeout = configReader->getSessionServerStartupTimeout().value();
151 :
152 23 : if (configReader->getHealthcheckInterval())
153 5 : m_healthcheckInterval = configReader->getHealthcheckInterval().value();
154 :
155 23 : if (configReader->getSocketPermissions())
156 5 : m_socketPermissions = configReader->getSocketPermissions().value();
157 :
158 23 : if (configReader->getSocketOwner())
159 5 : m_socketPermissions.owner = configReader->getSocketOwner().value();
160 :
161 23 : if (configReader->getSocketGroup())
162 5 : m_socketPermissions.group = configReader->getSocketGroup().value();
163 :
164 23 : if (configReader->getNumOfPreloadedServers())
165 5 : m_numOfPreloadedServers = configReader->getNumOfPreloadedServers().value();
166 :
167 23 : if (configReader->getNumOfPingsBeforeRecovery())
168 5 : m_numOfFailedPingsBeforeRecovery = configReader->getNumOfPingsBeforeRecovery().value();
169 :
170 23 : if (configReader->getLoggingLevels())
171 5 : m_loggingLevels = configReader->getLoggingLevels().value();
172 36 : }
173 :
174 13 : void ConfigHelper::mergeEnvVariables()
175 : {
176 : // Env vars from json are more important than values from config struct
177 13 : if (!m_envVarsFromConfigFile.empty())
178 : {
179 9 : m_sessionServerEnvVars = m_envVarsFromConfigFile;
180 : }
181 16 : for (const auto &[name, value] : m_extraEnvVarsFromConfigFile)
182 : {
183 : // If env variable exists both in envVariables and extraEnvVariables, overwrite it.
184 3 : m_sessionServerEnvVars[name] = value;
185 : }
186 13 : }
187 : #endif // RIALTO_ENABLE_CONFIG_FILE
188 : } // namespace rialto::servermanager::service
|