From 5595661037a8922a8ba639720fbe45a1550fd021 Mon Sep 17 00:00:00 2001 From: arjen Date: Sat, 3 Nov 2007 10:23:53 +0000 Subject: [PATCH] Handling of parameters is greatly improved. When creating a new parameter from an XML report which is fed into gcm_input, the class definition is used as a template to fill in the default values for the properties. The class is also used as a template when a new property is added to an existing parameter. DYNAMIC properties are now handled properly. Instead of making a 'changed property' notification, the value is checked against the defined range for the property. An 'out of range' notification is created when this condition is detected. --- src/gcm_input/message.cpp | 194 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 170 insertions(+), 24 deletions(-) diff --git a/src/gcm_input/message.cpp b/src/gcm_input/message.cpp index 24364b6..ce006fc 100644 --- a/src/gcm_input/message.cpp +++ b/src/gcm_input/message.cpp @@ -8,7 +8,7 @@ *********************** ** FILE NAME : message.cpp ** SYSTEM NAME : Gnucomo - Gnu Computer Monitoring -** VERSION NUMBER : $Revision: 1.17 $ +** VERSION NUMBER : $Revision: 1.18 $ ** ** DESCRIPTION : Implementation of the message handling classes ** @@ -20,13 +20,26 @@ ******************************** ** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl ** CREATION DATE : Sep 16, 2002 -** LAST UPDATE : Nov 28, 2003 +** LAST UPDATE : Nov 02, 2007 ** MODIFICATIONS : **************************************************************************/ /***************************** $Log: message.cpp,v $ - Revision 1.17 2005-05-31 05:51:41 arjen + Revision 1.18 2007-11-03 10:23:53 arjen + Handling of parameters is greatly improved. + When creating a new parameter from an XML report which is fed into + gcm_input, the class definition is used as a template to fill in + the default values for the properties. + The class is also used as a template when a new property is added + to an existing parameter. + + DYNAMIC properties are now handled properly. Instead of making a + 'changed property' notification, the value is checked against the + defined range for the property. An 'out of range' notification + is created when this condition is detected. + + Revision 1.17 2005/05/31 05:51:41 arjen Textual changes in parameter notifications Revision 1.16 2003/12/04 10:38:09 arjen @@ -100,7 +113,7 @@ *****************************/ -static const char *RCSID = "$Id: message.cpp,v 1.17 2005-05-31 05:51:41 arjen Exp $"; +static const char *RCSID = "$Id: message.cpp,v 1.18 2007-11-03 10:23:53 arjen Exp $"; #include #include @@ -373,7 +386,7 @@ double client_message::classify(String host, UTC arriv, String serv) uncertainty = 1.0; - while (input >> line && uncertainty > 0.1) + while (input >> line && uncertainty > epsilon) { if (verbose) { @@ -416,8 +429,6 @@ double client_message::classify(String host, UTC arriv, String serv) } } - //TODO: If uncertainty is still too great, pick the least uncertain. - input.rewind(); certainty = 1.0 - uncertainty; @@ -438,7 +449,7 @@ double client_message::classify(String host, UTC arriv, String serv) ** VARS CHANGED : ** FUNCTIONS USED : ** SEE ALSO : -** LAST MODIFIED : Nov 28, 2003 +** LAST MODIFIED : Nov 02, 2007 **========================================================================= */ @@ -446,6 +457,9 @@ struct param_property { String name; String value; + String type; + double minimum; + double maximum; }; void client_message::enterXML() @@ -629,17 +643,39 @@ void client_message::enterXML() String qry; String insertion; String change_notification(""); + String out_of_range_notification(""); String create_notification(""); String remove_notification(""); bool initial_entry = false; String param_class((const char *)xmlGetProp(node, (const xmlChar *)"class")); + std::list parameter_template; + int nr_properties; + + // Obtain a list of properties from the parameter's class. + // This list is used to create new parameters. + + qry = "select * from parameter_class where name='"; + qry += param_class + "'"; + nr_properties = database.Query(qry); + for (int i = 0; i < nr_properties; i++) + { + param_property pp; + + pp.name = database.Field(i, "property_name"); + pp.type = database.Field(i, "property_type"); + pp.minimum = database.Field(i, "min"); + pp.maximum = database.Field(i, "max"); + + parameter_template.push_back(pp); + } + #ifdef DEBUG *Log << "Entering a list of " << param_class << " parameters.\n"; #endif pathcontext->node = node; - // If we don;t have any parameters of this class, this will be + // If we don't have any parameters of this class, this will be // an initial entry. qry = "select name from parameter where objectid='"; @@ -703,43 +739,101 @@ void client_message::enterXML() // The parameter exists in the database; check all properties. bool param_changed = false; + bool out_of_range = false; paramid = database.Field(0, "paramid"); while (pi != properties.end()) { - qry = "select value from property where paramid='"; + qry = "select * from property where paramid='"; qry += paramid + "' and name='"; qry += pi->name + "'"; if (database.Query(qry) == 0) { *Log << "Property " << pi->name << " of " << param_name << " does not exist.\n"; - } - else if (database.Field(0, "value") != pi->value) - { - *Log << "Property " << pi->name << " of " - << param_name << " is different.\n"; + // Find the property in the template from the class. - insertion = "update property set value='"; - insertion += pi->value + "' where paramid='"; - insertion += paramid + "' and name='"; - insertion += pi->name + "'"; + String property_type("STATIC"); + double property_minimum = 0.0; + double property_maximum = 0.0; + std::list::iterator ti = parameter_template.begin(); + while (ti != parameter_template.end() && ti->name != pi->name) + { + ti++; + } + if (ti != parameter_template.end()) + { + property_type = ti->type; + property_minimum = ti->minimum; + property_maximum = ti->maximum; + } + + insertion = "insert into property (paramid, name, value, type, min, max) values ('"; + insertion += paramid + "', '"; + insertion += pi->name + "', '"; + insertion += pi->value + "', '"; + insertion += property_type + "', '"; + insertion += String(property_minimum) + "', '"; + insertion += String(property_maximum) + "')"; database.Query(insertion); insertion = "insert into history (paramid, modified,"; insertion += " change_nature, changed_property, new_value)"; insertion += " values ('"; insertion += paramid + "', '" + arrival.format("%Y-%m-%d %T") - + "', 'MODIFIED', '"; + + "', 'CREATED', '"; insertion += pi->name + "', '"; insertion += pi->value + "')"; - database.Query(insertion); + } + else + { + param_property stored_property; + + stored_property.value = database.Field(0, "value"); + stored_property.type = database.Field(0, "type"); + stored_property.minimum = database.Field(0, "min"); + stored_property.maximum = database.Field(0, "max"); - param_changed = true; + if (stored_property.value != pi->value) + { + *Log << "Property " << pi->name << " of " + << param_name << " is different.\n"; + + insertion = "update property set value='"; + insertion += pi->value + "' where paramid='"; + insertion += paramid + "' and name='"; + insertion += pi->name + "'"; + + database.Query(insertion); + insertion = "insert into history (paramid, modified,"; + insertion += " change_nature, changed_property, new_value)"; + insertion += " values ('"; + insertion += paramid + "', '" + arrival.format("%Y-%m-%d %T") + + "', 'MODIFIED', '"; + insertion += pi->name + "', '"; + insertion += pi->value + "')"; + database.Query(insertion); + if (stored_property.type == "DYNAMIC") + { + // Check the value against the range of the property. + + double numeric_value = pi->value; + if (numeric_value < stored_property.minimum || numeric_value > stored_property.maximum) + { + out_of_range = true; + } + } + else + { + // A STATIC property changed. + param_changed = true; + } + + } } pi++; } @@ -774,6 +868,37 @@ void client_message::enterXML() *Log << "gcm_input ERROR: Cannot create 'property modified' notification.\n"; } } + + if (out_of_range) + { + if (out_of_range_notification == "") + { + remark = "Gnucomo detected that a property value is out of range."; + out_of_range_notification = database.new_notification(objectid, + "property out of range", remark); + } + + if (out_of_range_notification != "") + { + qry = "select * from parameter_notification where notificationid='"; + qry += out_of_range_notification + "' and paramid='"; + qry += paramid + "'"; + + if (database.Query(qry) == 0) + { + insertion = "insert into parameter_notification"; + insertion += " (notificationid, paramid) values ('"; + insertion += out_of_range_notification + "', '"; + insertion += paramid + "')"; + + database.Query(insertion); + } + } + else + { + *Log << "gcm_input ERROR: Cannot create 'property out of range' notification.\n"; + } + } } else { @@ -794,10 +919,31 @@ void client_message::enterXML() while (pi != properties.end()) { - insertion = "insert into property (paramid, name, value, type) values ('"; + // Find the property in the template from the class. + + String property_type("STATIC"); + double property_minimum = 0.0; + double property_maximum = 0.0; + std::list::iterator ti = parameter_template.begin(); + + while (ti != parameter_template.end() && ti->name != pi->name) + { + ti++; + } + if (ti != parameter_template.end()) + { + property_type = ti->type; + property_minimum = ti->minimum; + property_maximum = ti->maximum; + } + + insertion = "insert into property (paramid, name, value, type, min, max) values ('"; insertion += paramid + "', '"; insertion += pi->name + "', '"; - insertion += pi->value + "', 'STATIC')"; + insertion += pi->value + "', '"; + insertion += property_type + "', '"; + insertion += String(property_minimum) + "', '"; + insertion += String(property_maximum) + "')"; database.Query(insertion); insertion = "insert into history (paramid, modified,"; -- 2.11.0