MXS-1220: Add PUT support for monitors
Monitor resources can now be altered with a PUT request. The method allows alterations on all parameters that the maxadmin `alter monitor` command allows.
This commit is contained in:

committed by
Markus Mäkelä

parent
690d592a94
commit
1e1c4abcb7
@ -377,7 +377,7 @@ static void add_monitor_defaults(MXS_MONITOR *monitor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runtime_alter_monitor(MXS_MONITOR *monitor, char *key, char *value)
|
bool runtime_alter_monitor(MXS_MONITOR *monitor, const char *key, const char *value)
|
||||||
{
|
{
|
||||||
spinlock_acquire(&crt_lock);
|
spinlock_acquire(&crt_lock);
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
@ -450,8 +450,8 @@ bool runtime_alter_monitor(MXS_MONITOR *monitor, char *key, char *value)
|
|||||||
if (value[0])
|
if (value[0])
|
||||||
{
|
{
|
||||||
MXS_CONFIG_PARAMETER p = {};
|
MXS_CONFIG_PARAMETER p = {};
|
||||||
p.name = key;
|
p.name = const_cast<char*>(key);
|
||||||
p.value = value;
|
p.value = const_cast<char*>(value);
|
||||||
monitorAddParameters(monitor, &p);
|
monitorAddParameters(monitor, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,7 +760,7 @@ static bool server_relation_is_valid(const string& type, const string& value)
|
|||||||
(type == CN_MONITORS && monitor_find(value.c_str()));
|
(type == CN_MONITORS && monitor_find(value.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool unlink_server_relations(SERVER* server, set<string>& relations)
|
static bool unlink_server_from_objects(SERVER* server, set<string>& relations)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
@ -775,7 +775,7 @@ static bool unlink_server_relations(SERVER* server, set<string>& relations)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool link_server_relations(SERVER* server, set<string>& relations)
|
static bool link_server_to_objects(SERVER* server, set<string>& relations)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
@ -783,7 +783,7 @@ static bool link_server_relations(SERVER* server, set<string>& relations)
|
|||||||
{
|
{
|
||||||
if (!runtime_link_server(server, it->c_str()))
|
if (!runtime_link_server(server, it->c_str()))
|
||||||
{
|
{
|
||||||
unlink_server_relations(server, relations);
|
unlink_server_from_objects(server, relations);
|
||||||
rval = false;
|
rval = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -820,7 +820,7 @@ SERVER* runtime_create_server_from_json(json_t* json)
|
|||||||
rval = server_find_by_unique_name(name);
|
rval = server_find_by_unique_name(name);
|
||||||
ss_dassert(rval);
|
ss_dassert(rval);
|
||||||
|
|
||||||
if (!link_server_relations(rval, relations))
|
if (!link_server_to_objects(rval, relations))
|
||||||
{
|
{
|
||||||
runtime_destroy_server(rval);
|
runtime_destroy_server(rval);
|
||||||
rval = NULL;
|
rval = NULL;
|
||||||
@ -831,7 +831,7 @@ SERVER* runtime_create_server_from_json(json_t* json)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_alter_server_relations(SERVER* server, json_t* old_json, json_t* new_json)
|
bool server_to_object_relations(SERVER* server, json_t* old_json, json_t* new_json)
|
||||||
{
|
{
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
set<string> old_relations;
|
set<string> old_relations;
|
||||||
@ -851,8 +851,8 @@ bool handle_alter_server_relations(SERVER* server, json_t* old_json, json_t* new
|
|||||||
old_relations.begin(), old_relations.end(),
|
old_relations.begin(), old_relations.end(),
|
||||||
std::inserter(added_relations, added_relations.begin()));
|
std::inserter(added_relations, added_relations.begin()));
|
||||||
|
|
||||||
if (link_server_relations(server, added_relations) &&
|
if (link_server_to_objects(server, added_relations) &&
|
||||||
unlink_server_relations(server, removed_relations))
|
unlink_server_from_objects(server, removed_relations))
|
||||||
{
|
{
|
||||||
rval = true;
|
rval = true;
|
||||||
}
|
}
|
||||||
@ -867,7 +867,7 @@ bool runtime_alter_server_from_json(SERVER* server, json_t* new_json)
|
|||||||
Closer<json_t*> old_json(server_to_json(server, ""));
|
Closer<json_t*> old_json(server_to_json(server, ""));
|
||||||
ss_dassert(old_json.get());
|
ss_dassert(old_json.get());
|
||||||
|
|
||||||
if (handle_alter_server_relations(server, old_json.get(), new_json))
|
if (server_to_object_relations(server, old_json.get(), new_json))
|
||||||
{
|
{
|
||||||
json_t* parameters = json_object_get(new_json, CN_PARAMETERS);
|
json_t* parameters = json_object_get(new_json, CN_PARAMETERS);
|
||||||
json_t* old_parameters = json_object_get(old_json.get(), CN_PARAMETERS);;
|
json_t* old_parameters = json_object_get(old_json.get(), CN_PARAMETERS);;
|
||||||
@ -907,18 +907,18 @@ static bool monitor_contains_required_fields(json_t* json)
|
|||||||
(value = json_object_get(json, CN_MODULE)) && json_is_string(value);
|
(value = json_object_get(json, CN_MODULE)) && json_is_string(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* monitor_relation_types[] =
|
const char* object_relation_types[] =
|
||||||
{
|
{
|
||||||
CN_SERVERS,
|
CN_SERVERS,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool monitor_relation_is_valid(const string& type, const string& value)
|
static bool object_relation_is_valid(const string& type, const string& value)
|
||||||
{
|
{
|
||||||
return type == CN_SERVERS && server_find_by_unique_name(value.c_str());
|
return type == CN_SERVERS && server_find_by_unique_name(value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool unlink_monitor_relations(MXS_MONITOR* monitor, set<string>& relations)
|
static bool unlink_object_from_servers(const char* target, set<string>& relations)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
@ -926,7 +926,7 @@ static bool unlink_monitor_relations(MXS_MONITOR* monitor, set<string>& relation
|
|||||||
{
|
{
|
||||||
SERVER* server = server_find_by_unique_name(it->c_str());
|
SERVER* server = server_find_by_unique_name(it->c_str());
|
||||||
|
|
||||||
if (!server || !runtime_unlink_server(server, monitor->name))
|
if (!server || !runtime_unlink_server(server, target))
|
||||||
{
|
{
|
||||||
rval = false;
|
rval = false;
|
||||||
break;
|
break;
|
||||||
@ -936,7 +936,7 @@ static bool unlink_monitor_relations(MXS_MONITOR* monitor, set<string>& relation
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool link_monitor_relations(MXS_MONITOR* monitor, set<string>& relations)
|
static bool link_object_to_servers(const char* target, set<string>& relations)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
@ -944,9 +944,9 @@ static bool link_monitor_relations(MXS_MONITOR* monitor, set<string>& relations)
|
|||||||
{
|
{
|
||||||
SERVER* server = server_find_by_unique_name(it->c_str());
|
SERVER* server = server_find_by_unique_name(it->c_str());
|
||||||
|
|
||||||
if (!server || !runtime_link_server(server, monitor->name))
|
if (!server || !runtime_link_server(server, target))
|
||||||
{
|
{
|
||||||
unlink_server_relations(server, relations);
|
unlink_server_from_objects(server, relations);
|
||||||
rval = false;
|
rval = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -966,13 +966,13 @@ MXS_MONITOR* runtime_create_monitor_from_json(json_t* json)
|
|||||||
|
|
||||||
set<string> relations;
|
set<string> relations;
|
||||||
|
|
||||||
if (extract_relations(json, relations, monitor_relation_types, monitor_relation_is_valid) &&
|
if (extract_relations(json, relations, object_relation_types, object_relation_is_valid) &&
|
||||||
runtime_create_monitor(name, module))
|
runtime_create_monitor(name, module))
|
||||||
{
|
{
|
||||||
rval = monitor_find(name);
|
rval = monitor_find(name);
|
||||||
ss_dassert(rval);
|
ss_dassert(rval);
|
||||||
|
|
||||||
if (!link_monitor_relations(rval, relations))
|
if (!link_object_to_servers(rval->name, relations))
|
||||||
{
|
{
|
||||||
runtime_destroy_monitor(rval);
|
runtime_destroy_monitor(rval);
|
||||||
rval = NULL;
|
rval = NULL;
|
||||||
@ -982,3 +982,83 @@ MXS_MONITOR* runtime_create_monitor_from_json(json_t* json)
|
|||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool object_to_server_relations(const char* target, json_t* old_json, json_t* new_json)
|
||||||
|
{
|
||||||
|
bool rval = false;
|
||||||
|
set<string> old_relations;
|
||||||
|
set<string> new_relations;
|
||||||
|
|
||||||
|
if (extract_relations(old_json, old_relations, object_relation_types, object_relation_is_valid) &&
|
||||||
|
extract_relations(new_json, new_relations, object_relation_types, object_relation_is_valid))
|
||||||
|
{
|
||||||
|
set<string> removed_relations;
|
||||||
|
set<string> added_relations;
|
||||||
|
|
||||||
|
std::set_difference(old_relations.begin(), old_relations.end(),
|
||||||
|
new_relations.begin(), new_relations.end(),
|
||||||
|
std::inserter(removed_relations, removed_relations.begin()));
|
||||||
|
|
||||||
|
std::set_difference(new_relations.begin(), new_relations.end(),
|
||||||
|
old_relations.begin(), old_relations.end(),
|
||||||
|
std::inserter(added_relations, added_relations.begin()));
|
||||||
|
|
||||||
|
if (link_object_to_servers(target, added_relations) &&
|
||||||
|
unlink_object_from_servers(target, removed_relations))
|
||||||
|
{
|
||||||
|
rval = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runtime_alter_monitor_from_json(MXS_MONITOR* monitor, json_t* new_json)
|
||||||
|
{
|
||||||
|
bool rval = false;
|
||||||
|
Closer<json_t*> old_json(monitor_to_json(monitor, ""));
|
||||||
|
ss_dassert(old_json.get());
|
||||||
|
|
||||||
|
if (object_to_server_relations(monitor->name, old_json.get(), new_json))
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
json_t* parameters = json_object_get(new_json, CN_PARAMETERS);
|
||||||
|
json_t* old_parameters = json_object_get(old_json.get(), CN_PARAMETERS);;
|
||||||
|
ss_dassert(old_parameters);
|
||||||
|
|
||||||
|
if (parameters)
|
||||||
|
{
|
||||||
|
rval = true;
|
||||||
|
const char* key;
|
||||||
|
json_t* value;
|
||||||
|
|
||||||
|
json_object_foreach(parameters, key, value)
|
||||||
|
{
|
||||||
|
json_t* new_val = json_object_get(parameters, key);
|
||||||
|
json_t* old_val = json_object_get(old_parameters, key);
|
||||||
|
|
||||||
|
if (old_val && new_val && mxs::json_to_string(new_val) == mxs::json_to_string(old_val))
|
||||||
|
{
|
||||||
|
/** No change in values */
|
||||||
|
}
|
||||||
|
else if (runtime_alter_monitor(monitor, key, mxs::json_to_string(value).c_str()))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
/** A configuration change was made, restart the monitor */
|
||||||
|
monitorStop(monitor);
|
||||||
|
monitorStart(monitor, monitor->parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
@ -118,7 +118,7 @@ bool runtime_enable_server_ssl(SERVER *server, const char *key, const char *cert
|
|||||||
* @param value New value
|
* @param value New value
|
||||||
* @return True if @c key was one of the supported parameters
|
* @return True if @c key was one of the supported parameters
|
||||||
*/
|
*/
|
||||||
bool runtime_alter_monitor(MXS_MONITOR *monitor, char *key, char *value);
|
bool runtime_alter_monitor(MXS_MONITOR *monitor, const char *key, const char *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new listener for a service
|
* @brief Create a new listener for a service
|
||||||
@ -192,7 +192,7 @@ SERVER* runtime_create_server_from_json(json_t* json);
|
|||||||
* @brief Alter a server using JSON
|
* @brief Alter a server using JSON
|
||||||
*
|
*
|
||||||
* @param server Server to alter
|
* @param server Server to alter
|
||||||
* @param new_json JSON definition of the new server
|
* @param new_json JSON definition of the updated server
|
||||||
*
|
*
|
||||||
* @return True if the server was successfully modified to represent @c new_json
|
* @return True if the server was successfully modified to represent @c new_json
|
||||||
*/
|
*/
|
||||||
@ -207,4 +207,14 @@ bool runtime_alter_server_from_json(SERVER* server, json_t* new_json);
|
|||||||
*/
|
*/
|
||||||
MXS_MONITOR* runtime_create_monitor_from_json(json_t* json);
|
MXS_MONITOR* runtime_create_monitor_from_json(json_t* json);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alter a monitor using JSON
|
||||||
|
*
|
||||||
|
* @param monitor Monitor to alter
|
||||||
|
* @param new_json JSON definition of the updated monitor
|
||||||
|
*
|
||||||
|
* @return True if the monitor was successfully modified to represent @c new_json
|
||||||
|
*/
|
||||||
|
bool runtime_alter_monitor_from_json(MXS_MONITOR* monitor, json_t* new_json);
|
||||||
|
|
||||||
MXS_END_DECLS
|
MXS_END_DECLS
|
||||||
|
@ -58,7 +58,7 @@ RESULTSET *monitorGetList();
|
|||||||
|
|
||||||
bool monitorAddServer(MXS_MONITOR *mon, SERVER *server);
|
bool monitorAddServer(MXS_MONITOR *mon, SERVER *server);
|
||||||
void monitorRemoveServer(MXS_MONITOR *mon, SERVER *server);
|
void monitorRemoveServer(MXS_MONITOR *mon, SERVER *server);
|
||||||
void monitorAddUser(MXS_MONITOR *, char *, char *);
|
void monitorAddUser(MXS_MONITOR *, const char *, const char *);
|
||||||
void monitorAddParameters(MXS_MONITOR *monitor, MXS_CONFIG_PARAMETER *params);
|
void monitorAddParameters(MXS_MONITOR *monitor, MXS_CONFIG_PARAMETER *params);
|
||||||
bool monitorRemoveParameter(MXS_MONITOR *monitor, const char *key);
|
bool monitorRemoveParameter(MXS_MONITOR *monitor, const char *key);
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ void monitorRemoveServer(MXS_MONITOR *mon, SERVER *server)
|
|||||||
* @param passwd The default password associated to the default user.
|
* @param passwd The default password associated to the default user.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
monitorAddUser(MXS_MONITOR *mon, char *user, char *passwd)
|
monitorAddUser(MXS_MONITOR *mon, const char *user, const char *passwd)
|
||||||
{
|
{
|
||||||
if (user != mon->user)
|
if (user != mon->user)
|
||||||
{
|
{
|
||||||
@ -1535,6 +1535,8 @@ json_t* monitor_parameters_to_json(const MXS_MONITOR* monitor)
|
|||||||
{
|
{
|
||||||
json_t* rval = json_object();
|
json_t* rval = json_object();
|
||||||
|
|
||||||
|
json_object_set_new(rval, CN_USER, json_string(monitor->user));
|
||||||
|
json_object_set_new(rval, CN_PASSWORD, json_string(monitor->password));
|
||||||
json_object_set_new(rval, CN_MONITOR_INTERVAL, json_integer(monitor->interval));
|
json_object_set_new(rval, CN_MONITOR_INTERVAL, json_integer(monitor->interval));
|
||||||
json_object_set_new(rval, CN_BACKEND_CONNECT_TIMEOUT, json_integer(monitor->connect_timeout));
|
json_object_set_new(rval, CN_BACKEND_CONNECT_TIMEOUT, json_integer(monitor->connect_timeout));
|
||||||
json_object_set_new(rval, CN_BACKEND_READ_TIMEOUT, json_integer(monitor->read_timeout));
|
json_object_set_new(rval, CN_BACKEND_READ_TIMEOUT, json_integer(monitor->read_timeout));
|
||||||
|
@ -158,6 +158,23 @@ HttpResponse cb_create_monitor(const HttpRequest& request)
|
|||||||
return HttpResponse(MHD_HTTP_BAD_REQUEST);
|
return HttpResponse(MHD_HTTP_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpResponse cb_alter_monitor(const HttpRequest& request)
|
||||||
|
{
|
||||||
|
json_t* json = request.get_json();
|
||||||
|
|
||||||
|
if (json)
|
||||||
|
{
|
||||||
|
MXS_MONITOR* monitor = monitor_find(request.uri_part(1).c_str());
|
||||||
|
|
||||||
|
if (monitor && runtime_alter_monitor_from_json(monitor, json))
|
||||||
|
{
|
||||||
|
return HttpResponse(MHD_HTTP_OK, monitor_to_json(monitor, request.host()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResponse(MHD_HTTP_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
HttpResponse cb_all_servers(const HttpRequest& request)
|
HttpResponse cb_all_servers(const HttpRequest& request)
|
||||||
{
|
{
|
||||||
return HttpResponse(MHD_HTTP_OK, server_list_to_json(request.host()));
|
return HttpResponse(MHD_HTTP_OK, server_list_to_json(request.host()));
|
||||||
@ -334,6 +351,7 @@ public:
|
|||||||
m_post.push_back(SResource(new Resource(cb_create_monitor, 1, "monitors")));
|
m_post.push_back(SResource(new Resource(cb_create_monitor, 1, "monitors")));
|
||||||
|
|
||||||
m_put.push_back(SResource(new Resource(cb_alter_server, 2, "servers", ":server")));
|
m_put.push_back(SResource(new Resource(cb_alter_server, 2, "servers", ":server")));
|
||||||
|
m_put.push_back(SResource(new Resource(cb_alter_monitor, 2, "monitors", ":monitor")));
|
||||||
}
|
}
|
||||||
|
|
||||||
~RootResource()
|
~RootResource()
|
||||||
|
Reference in New Issue
Block a user