Factor out module parameter set extraction

Factored out the extraction of the parameter set that a module has. Also
cleaned up the configuration to use STL containers and types.
This commit is contained in:
Markus Mäkelä
2018-07-29 23:33:58 +03:00
parent 1e33ab69f2
commit d95b1f834d

View File

@ -28,9 +28,14 @@
#include <string.h>
#include <sys/ioctl.h>
#include <ini.h>
#include <fstream>
#include <functional>
#include <numeric>
#include <set>
#include <string>
#include <fstream>
#include <tuple>
#include <utility>
#include <vector>
#include <maxscale/adminusers.h>
@ -1118,6 +1123,73 @@ config_load(const char *filename)
return rval;
}
bool valid_object_type(std::string type)
{
std::set<std::string> types{CN_SERVICE, CN_LISTENER, CN_SERVER, CN_MONITOR, CN_FILTER};
return types.count(type);
}
/**
* Get the value of a config parameter
*
* @param params The linked list of config parameters
* @param name The parameter to return
* @return the parameter value or NULL if not found
*/
static char* config_get_value(MXS_CONFIG_PARAMETER *params, const char *name)
{
while (params)
{
if (!strcmp(params->name, name))
{
return params->value;
}
params = params->next;
}
return NULL;
}
const MXS_MODULE* get_module(CONFIG_CONTEXT* obj, const char* param_name, const char* module_type)
{
const char* module = config_get_value(obj->parameters, param_name);
return module ? get_module(module, module_type) : NULL;
}
std::pair<const MXS_MODULE_PARAM*, const MXS_MODULE*> get_module_details(CONFIG_CONTEXT* obj)
{
std::string type = config_get_string(obj->parameters, CN_TYPE);
if (type == CN_SERVICE)
{
const char* name = config_get_string(obj->parameters, CN_ROUTER);
return {config_service_params, get_module(name, MODULE_ROUTER)};
}
else if (type == CN_LISTENER)
{
const char* name = config_get_string(obj->parameters, CN_PROTOCOL);
return {config_listener_params, get_module(name, MODULE_PROTOCOL)};
}
else if (type == CN_SERVER)
{
const char* name = config_get_string(obj->parameters, CN_PROTOCOL);
return {config_server_params, get_module(name, MODULE_PROTOCOL)};
}
else if (type == CN_MONITOR)
{
const char* name = config_get_string(obj->parameters, CN_MODULE);
return {config_monitor_params, get_module(name, MODULE_MONITOR)};
}
else if (type == CN_FILTER)
{
const char* name = config_get_string(obj->parameters, CN_MODULE);
return {config_filter_params, get_module(name, MODULE_FILTER)};
}
ss_dassert(!true);
return {nullptr, nullptr};
}
/**
* @brief Process a configuration context and turn it into the set of objects
*
@ -1135,37 +1207,23 @@ process_config_context(CONFIG_CONTEXT *context)
* Process the data and create the services and servers defined
* in the data.
*/
obj = context;
while (obj)
for (CONFIG_CONTEXT* obj : objects)
{
if (is_maxscale_section(obj->object))
{
obj = obj->next;
continue;
}
std::string type = config_get_string(obj->parameters, CN_TYPE);
ss_dassert(!type.empty());
char *type = config_get_value(obj->parameters, CN_TYPE);
if (type)
if (type == CN_SERVICE)
{
if (!strcmp(type, CN_SERVICE))
{
error_count += create_new_service(obj);
}
else if (!strcmp(type, "server"))
{
error_count += create_new_server(obj);
}
else if (!strcmp(type, "filter"))
{
error_count += create_new_filter(obj);
}
error_count += create_new_service(obj);
}
else
else if (type == CN_SERVER)
{
MXS_ERROR("Configuration object '%s' has no type.", obj->object);
error_count++;
error_count += create_new_server(obj);
}
else if (type == CN_FILTER)
{
error_count += create_new_filter(obj);
}
obj = obj->next;
}
if (error_count == 0)
@ -1175,52 +1233,28 @@ process_config_context(CONFIG_CONTEXT *context)
* servers and filters to the services. Monitors are also created at this point
* because they require a set of servers to monitor.
*/
obj = context;
while (obj)
{
if (is_maxscale_section(obj->object))
{
obj = obj->next;
continue;
}
char *type = config_get_value(obj->parameters, CN_TYPE);
if (type)
std::set<std::string> monitored_servers;
for (CONFIG_CONTEXT* obj : objects)
{
std::string type = config_get_string(obj->parameters, CN_TYPE);
ss_dassert(!type.empty());
if (type == CN_SERVICE)
{
if (!strcmp(type, CN_SERVICE))
{
error_count += configure_new_service(obj);
}
else if (!strcmp(type, CN_LISTENER))
{
error_count += create_new_listener(obj);
}
else if (!strcmp(type, CN_MONITOR))
{
error_count += create_new_monitor(obj, monitored_servers);
}
else if (strcmp(type, CN_SERVER) != 0 && strcmp(type, CN_FILTER) != 0)
{
MXS_ERROR("Configuration object '%s' has an invalid type specified.",
obj->object);
error_count++;
}
error_count += configure_new_service(obj);
}
else if (type == CN_LISTENER)
{
error_count += create_new_listener(obj);
}
else if (type == CN_MONITOR)
{
error_count += create_new_monitor(obj, monitored_servers);
}
obj = obj->next;
}
}
/** TODO: consistency check function */
/**
* error_count += consistency_checks();
*/
#ifdef REQUIRE_LISTENERS
if (!service_all_services_have_listeners())
{
error_count++;
}
#endif
if (error_count)
{
@ -1231,28 +1265,6 @@ process_config_context(CONFIG_CONTEXT *context)
return error_count == 0;
}
/**
* Get the value of a config parameter
*
* @param params The linked list of config parameters
* @param name The parameter to return
* @return the parameter value or NULL if not found
*/
static char *
config_get_value(MXS_CONFIG_PARAMETER *params, const char *name)
{
while (params)
{
if (!strcmp(params->name, name))
{
return params->value;
}
params = params->next;
}
return NULL;
}
// DEPRECATE: In 2.1 complain but accept if "passwd" is provided, in 2.2
// DEPRECATE: drop support for "passwd".
/**
@ -2489,51 +2501,21 @@ check_config_objects(CONFIG_CONTEXT *context)
continue;
}
const MXS_MODULE_PARAM* param_set = NULL;
const char *module = NULL;
const char *module_type = NULL;
const char *type = config_get_string(obj->parameters, CN_TYPE);
std::string type = config_get_string(obj->parameters, CN_TYPE);
if (!strcmp(type, CN_SERVICE))
if (!valid_object_type(type))
{
param_set = config_service_params;
module = config_get_value(obj->parameters, CN_ROUTER);
module_type = MODULE_ROUTER;
}
else if (!strcmp(type, CN_LISTENER))
{
param_set = config_listener_params;
module = config_get_value(obj->parameters, CN_PROTOCOL);
module_type = MODULE_PROTOCOL;
}
else if (!strcmp(type, CN_SERVER))
{
param_set = config_server_params;
module = config_get_value(obj->parameters, CN_PROTOCOL);
module_type = MODULE_PROTOCOL;
}
else if (!strcmp(type, CN_MONITOR))
{
param_set = config_monitor_params;
module = config_get_value(obj->parameters, CN_MODULE);
module_type = MODULE_MONITOR;
}
else if (!strcmp(type, CN_FILTER))
{
param_set = config_filter_params;
module = config_get_value(obj->parameters, CN_MODULE);
module_type = MODULE_FILTER;
}
else
{
MXS_ERROR("Unknown module type for object '%s': %s", obj->object, type);
MXS_ERROR("Unknown module type for object '%s': %s", obj->object, type.c_str());
rval = false;
continue;
}
const MXS_MODULE_PARAM* param_set = nullptr;
const MXS_MODULE *mod = nullptr;
std::tie(param_set, mod) = get_module_details(obj);
ss_dassert(param_set);
std::vector<std::string> to_be_removed;
const MXS_MODULE *mod = module ? get_module(module, module_type) : NULL;
for (MXS_CONFIG_PARAMETER *params = obj->parameters; params; params = params->next)
{
@ -2551,10 +2533,10 @@ check_config_objects(CONFIG_CONTEXT *context)
{
// Server's "need" to ignore any unknown parameters as they could
// be used as weighting parameters
if (strcmp(type, CN_SERVER) != 0)
if (type != CN_SERVER)
{
MXS_ERROR("Unknown parameter '%s' for object '%s' of type '%s'",
params->name, obj->object, type);
params->name, obj->object, type.c_str());
rval = false;
}
continue;
@ -2580,7 +2562,7 @@ check_config_objects(CONFIG_CONTEXT *context)
{
MXS_ERROR("Invalid value for parameter '%s' for object '%s' "
"of type '%s': %s (was expecting %s)",
params->name, params->value, obj->object, type,
params->name, params->value, obj->object, type.c_str(),
param_type_to_str(fix_params, params->name));
rval = false;
}