17 #include <boost/algorithm/string.hpp>
18 #include <boost/foreach.hpp>
26 const time_t DatabaseConnection::MAX_DB_TIME = 2147483647;
29 DatabaseConnection::getParameter(
const std::string& name)
const {
30 ParameterMap::const_iterator param = parameters_.find(name);
31 if (param == parameters_.end()) {
34 return (param->second);
38 DatabaseConnection::parse(
const std::string& dbaccess) {
40 std::string dba = dbaccess;
48 std::string password_prefix =
"password='";
49 auto password_pos = dba.find(password_prefix);
50 if (password_pos != string::npos) {
52 auto password_end_pos = dba.find(
'\'', password_pos + password_prefix.length());
53 if (password_end_pos == string::npos) {
59 auto password = dba.substr(password_pos + password_prefix.length(),
60 password_end_pos - password_pos - password_prefix.length());
61 mapped_tokens.insert(make_pair(
"password", password));
66 dba.erase(password_pos, password_prefix.length() + password.length() + 2);
72 return (mapped_tokens);
80 boost::split(tokens, dba, boost::is_any_of(
string(
"\t ")));
81 BOOST_FOREACH(std::string token, tokens) {
82 size_t pos = token.find(
"=");
83 if (pos != string::npos) {
84 string name = token.substr(0, pos);
85 string value = token.substr(pos + 1);
86 mapped_tokens.insert(make_pair(name, value));
89 <<
", expected format is name=value");
92 }
catch (
const std::exception& ex) {
99 return (mapped_tokens);
103 DatabaseConnection::redactedAccessString(
const ParameterMap& parameters) {
107 for (DatabaseConnection::ParameterMap::const_iterator i = parameters.begin();
108 i != parameters.end(); ++i) {
111 if (!access.empty()) {
121 if (i->first == std::string(
"password")) {
132 DatabaseConnection::configuredReadOnly()
const {
133 std::string readonly_value =
"false";
135 readonly_value = getParameter(
"readonly");
136 boost::algorithm::to_lower(readonly_value);
142 if ((readonly_value !=
"false") && (readonly_value !=
"true")) {
144 <<
"' specified for boolean parameter 'readonly'");
147 return (readonly_value ==
"true");
151 DatabaseConnection::makeReconnectCtl(
const std::string& timer_name) {
152 string type =
"unknown";
153 unsigned int retries = 0;
154 unsigned int interval = 0;
158 type = getParameter(
"type");
163 std::string parm_str;
165 parm_str = getParameter(
"max-reconnect-tries");
166 retries = boost::lexical_cast<
unsigned int>(parm_str);
172 parm_str = getParameter(
"reconnect-wait-time");
173 interval = boost::lexical_cast<
unsigned int>(parm_str);
180 parm_str = getParameter(
"on-fail");
181 action = ReconnectCtl::onFailActionFromText(parm_str);
186 reconnect_ctl_ = boost::make_shared<ReconnectCtl>(type, timer_name, retries,
192 if (DatabaseConnection::db_lost_callback_) {
193 return (DatabaseConnection::db_lost_callback_(db_reconnect_ctl));
200 DatabaseConnection::invokeDbRecoveredCallback(
const ReconnectCtlPtr& db_reconnect_ctl) {
201 if (DatabaseConnection::db_recovered_callback_) {
202 return (DatabaseConnection::db_recovered_callback_(db_reconnect_ctl));
210 if (DatabaseConnection::db_failed_callback_) {
211 return (DatabaseConnection::db_failed_callback_(db_reconnect_ctl));
221 for (
auto param: params) {
222 std::string keyword = param.first;
223 std::string value = param.second;
225 if ((keyword ==
"lfc-interval") ||
226 (keyword ==
"connect-timeout") ||
227 (keyword ==
"reconnect-wait-time") ||
228 (keyword ==
"max-reconnect-tries") ||
229 (keyword ==
"request-timeout") ||
230 (keyword ==
"tcp-keepalive") ||
231 (keyword ==
"port") ||
232 (keyword ==
"max-row-errors")) {
236 int_value = boost::lexical_cast<int64_t>(value);
240 .arg(
"integer").arg(keyword).arg(value);
242 }
else if ((keyword ==
"persist") ||
243 (keyword ==
"tcp-nodelay") ||
244 (keyword ==
"readonly")) {
245 if (value ==
"true") {
247 }
else if (value ==
"false") {
251 .arg(
"boolean").arg(keyword).arg(value);
253 }
else if ((keyword ==
"type") ||
254 (keyword ==
"user") ||
255 (keyword ==
"password") ||
256 (keyword ==
"host") ||
257 (keyword ==
"name") ||
258 (keyword ==
"contact-points") ||
259 (keyword ==
"consistency") ||
260 (keyword ==
"serial-consistency") ||
261 (keyword ==
"keyspace") ||
262 (keyword ==
"on-fail")) {
266 .arg(
"unknown").arg(keyword).arg(value);
274 DatabaseConnection::toElementDbAccessString(
const std::string& dbaccess) {
276 return (toElement(params));
282 case OnFailAction::STOP_RETRY_EXIT:
283 return (
"stop-retry-exit");
284 case OnFailAction::SERVE_RETRY_EXIT:
285 return (
"serve-retry-exit");
286 case OnFailAction::SERVE_RETRY_CONTINUE:
287 return (
"serve-retry-continue");
289 return (
"invalid-action-type");
293 ReconnectCtl::onFailActionFromText(
const std::string& text) {
294 if (text ==
"stop-retry-exit") {
295 return (OnFailAction::STOP_RETRY_EXIT);
296 }
else if (text ==
"serve-retry-exit") {
297 return (OnFailAction::SERVE_RETRY_EXIT);
298 }
else if (text ==
"serve-retry-continue") {
299 return (OnFailAction::SERVE_RETRY_CONTINUE);
305 DbCallback DatabaseConnection::db_lost_callback_ = 0;
306 DbCallback DatabaseConnection::db_recovered_callback_ = 0;
307 DbCallback DatabaseConnection::db_failed_callback_ = 0;
We want to reuse the database backend connection and exchange code for other uses, in particular for hook libraries.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
DB_LOG & arg(T first, Args...args)
Pass parameters to replace logger placeholders.
const isc::log::MessageID DATABASE_TO_JSON_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
boost::shared_ptr< Element > ElementPtr
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
OnFailAction
Type of action to take on connection loss.
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
Defines the logger used by the top-level component of kea-dhcp-ddns.
std::function< bool(ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Invalid 'readonly' value specification.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
isc::log::Logger database_logger("database")
Common database library logger.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.