CommandMgr::instance().registerCommand("statistic-remove",
boost::bind(&StatsMgr::statisticRemoveHandler, _1, _2));
+ //CommandMgr::instance().registerCommand("statistic-setMaxSampleAge",
+ // boost::bind(&StatsMgr::statisticSetMaxSampleAgeHandler, _1, _2));
+
+ //CommandMgr::instance().registerCommand("statistic-setMaxSampleCount",
+ // boost::bind(&StatsMgr::statisticSetMaxSampleCountHandler, _1, _2));
+
CommandMgr::instance().registerCommand("statistic-get-all",
boost::bind(&StatsMgr::statisticGetAllHandler, _1, _2));
CommandMgr::instance().deregisterCommand("statistic-remove-all");
CommandMgr::instance().deregisterCommand("statistic-reset");
CommandMgr::instance().deregisterCommand("statistic-reset-all");
+ //CommandMgr::instance().deregisterCommand("statistic-setMaxSampleAge");
+ //CommandMgr::instance().deregisterCommand("statistic-setMaxSampleCount");
CommandMgr::instance().deregisterCommand("version-get");
} catch (...) {
CommandMgr::instance().registerCommand("statistic-remove-all",
boost::bind(&StatsMgr::statisticRemoveAllHandler, _1, _2));
+
+ CommandMgr::instance().registerCommand("statistic-setMaxSampleAge",
+ boost::bind(&StatsMgr::statisticSetMaxSampleAgeHandler, _1, _2));
+
+ CommandMgr::instance().registerCommand("statistic-setMaxSampleCount",
+ boost::bind(&StatsMgr::statisticSetMaxSampleCountHandler, _1, _2));
}
void ControlledDhcpv6Srv::shutdown() {
return (global_->stats_.size());
}
+isc::data::ConstElementPtr
+StatsMgr::statisticSetMaxSampleAgeHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& params) {
+ std::string name, error;
+ StatsDuration duration;
+ if (!getStatName(params, name, error)) {
+ return (createAnswer(CONTROL_RESULT_ERROR, error));
+ }
+ if (!getStatDuration(params, duration, error)) {
+ return (createAnswer(CONTROL_RESULT_ERROR, error));
+ }
+ if (instance().setMaxSampleAge(name, duration)) {
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "Statistic '" + name + "' duration limit is set."));
+ //"Statistic '" + name + "' duration limit is set to " + std::to_string(duration) + "."));
+ } else {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "No '" + name + "' statistic found"));
+ }
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticSetMaxSampleCountHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& params) {
+ std::string name, error;
+ uint32_t max_samples;
+ if (!getStatName(params, name, error)) {
+ return (createAnswer(CONTROL_RESULT_ERROR, error));
+ }
+ if (!getStatMaxSamples(params, max_samples, error)) {
+ return (createAnswer(CONTROL_RESULT_ERROR, error));
+ }
+ if (instance().setMaxSampleCount(name, max_samples)) {
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "Statistic '" + name + "' count limit is set."));
+ //"Statistic '" + name + "' count limit is set to " + std::to_string(max_samples) + "."));
+ } else {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "No '" + name + "' statistic found"));
+ }
+}
+
isc::data::ConstElementPtr
StatsMgr::statisticGetHandler(const std::string& /*name*/,
const isc::data::ConstElementPtr& params) {
return (true);
}
+bool
+StatsMgr::getStatDuration(const isc::data::ConstElementPtr& params,
+ StatsDuration& duration,
+ std::string& reason) {
+ if (!params) {
+ reason = "Missing mandatory 'duration' parameters.";
+ return (false);
+ }
+ ConstElementPtr stat_hours = params->get("hours");
+ if (!stat_hours) {
+ reason = "Missing mandatory 'hours' parameter.";
+ return (false);
+ }
+ if (stat_hours->getType() != Element::integer) {
+ reason = "'hours' parameter expected to be an integer.";
+ return (false);
+ }
+ ConstElementPtr stat_minutes = params->get("minutes");
+ if (!stat_minutes) {
+ reason = "Missing mandatory 'minutes' parameter.";
+ return (false);
+ }
+ if (stat_minutes->getType() != Element::integer) {
+ reason = "'minutes' parameter expected to be an integer.";
+ return (false);
+ }
+ ConstElementPtr stat_seconds = params->get("seconds");
+ if (!stat_seconds) {
+ reason = "Missing mandatory 'seconds' parameter.";
+ return (false);
+ }
+ if (stat_seconds->getType() != Element::integer) {
+ reason = "'seconds' parameter expected to be an integer.";
+ return (false);
+ }
+ ConstElementPtr stat_milliseconds = params->get("milliseconds");
+ if (!stat_milliseconds) {
+ reason = "Missing mandatory 'milliseconds' parameter.";
+ return (false);
+ }
+ if (stat_milliseconds->getType() != Element::integer) {
+ reason = "'milliseconds' parameter expected to be an integer.";
+ return (false);
+ }
+ int64_t hours = stat_hours->intValue();
+ int64_t minutes = stat_minutes->intValue();
+ int64_t seconds = stat_seconds->intValue();
+ int64_t milliseconds = stat_milliseconds->intValue();
+ duration = boost::posix_time::time_duration(hours,minutes,seconds,milliseconds);
+ return (true);
+}
+
+bool
+StatsMgr::getStatMaxSamples(const isc::data::ConstElementPtr& params,
+ uint32_t& max_samples,
+ std::string& reason) {
+ if (!params) {
+ reason = "Missing mandatory 'max_samples' parameter.";
+ return (false);
+ }
+ ConstElementPtr stat_max_samples = params->get("max_samples");
+ if (!stat_max_samples) {
+ reason = "Missing mandatory 'max_samples' parameter.";
+ return (false);
+ }
+ if (stat_max_samples->getType() != Element::integer) {
+ reason = "'max_samples' parameter expected to be an integer.";
+ return (false);
+ }
+
+ max_samples = stat_max_samples->intValue();
+ return (true);
+}
+
};
};
statisticRemoveHandler(const std::string& name,
const isc::data::ConstElementPtr& params);
+ /// @brief Handles statistic-setMaxSampleAge command
+ ///
+ /// This method handles statistic-setMaxSampleAge command, which set max_sample_age
+ /// limit of a given statistic and leaves max_sample_count disabled.
+ /// It expects five parameters stored in params map:
+ /// name: name-of-the-statistic
+ /// duration limit of gathering samples given in four parameters:
+ /// hours, minutes, seconds and milliseconds
+ ///
+ /// Example params structure:
+ /// {
+ /// "name": "packets-received",
+ /// "hours": 0,
+ /// "minutes": 5,
+ /// "seconds": 0,
+ /// "milliseconds": 0
+ /// }
+ ///
+ /// @param name name of the command (ignored, should be "statistic-setMaxSampleAge")
+ /// @param params structure containing a map that contains "name" and "duration"
+ /// @return answer containing information about current statistic's limits
+ static isc::data::ConstElementPtr
+ statisticSetMaxSampleAgeHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @brief Handles statistic-setMaxSampleAge command
+ ///
+ /// This method handles statistic-setMaxSampleAge command, which set max_sample_age
+ /// limit of a given statistic and leaves max_sample_age disabled.
+ /// It expects two parameters stored in params map:
+ /// name: name-of-the-statistic
+ /// duration: duration limit of gathering samples
+ ///
+ /// Example params structure:
+ /// {
+ /// "name": "packets-received",
+ /// "max_samples": 15
+ /// }
+ ///
+ /// @param name name of the command (ignored, should be "statistic-setMaxSampleCount")
+ /// @param params structure containing a map that contains "name" and "max_samples"
+ /// @return answer containing information about current statistic's limits
+ static isc::data::ConstElementPtr
+ statisticSetMaxSampleCountHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
/// @brief Handles statistic-get-all command
///
/// This method handles statistic-get-all command, which returns values
std::string& name,
std::string& reason);
+ /// @brief Utility method that attempts to extract duration limit for
+ /// a given statistic
+ ///
+ /// This method attempts to extract duration limit for a given statistic
+ /// from the params structure.
+ /// It is expected to be a map that contains four 'duration' elements: 'hours',
+ /// 'minutes', 'seconds' and 'milliseconds'
+ /// all are of type int. If present as expected, statistic duration
+ /// limit is set and true is returned.
+ /// If any of these four parameters is missing or is of incorrect type,
+ /// the reason is specified in reason parameter and false is returned.
+ ///
+ /// @param params parameters structure received in command
+ /// @param duration [out] duration limit for the statistic (if no error detected)
+ /// @param reason [out] failure reason (if error is detected)
+ /// @return true (if everything is ok), false otherwise
+ static bool getStatDuration(const isc::data::ConstElementPtr& params,
+ StatsDuration& duration,
+ std::string& reason);
+
+ /// @brief Utility method that attempts to extract count limit for
+ /// a given statistic
+ ///
+ /// This method attempts to extract count limit for a given statistic
+ /// from the params structure.
+ /// It is expected to be a map that contains 'max_samples' element,
+ /// that is of type int. If present as expected, statistic count
+ /// limit (max_samples) is set and true is returned.
+ /// If missing or is of incorrect type, the reason is specified in reason
+ /// parameter and false is returned.
+ ///
+ /// @param params parameters structure received in command
+ /// @param max_samples [out] count limit for the statistic (if no error detected)
+ /// @param reason [out] failure reason (if error is detected)
+ /// @return true (if everything is ok), false otherwise
+ static bool getStatMaxSamples(const isc::data::ConstElementPtr& params,
+ uint32_t& max_samples,
+ std::string& reason);
+
// This is a global context. All statistics will initially be stored here.
StatContextPtr global_;
};
EXPECT_EQ(0, StatsMgr::instance().count());
}
+// This test checks whether statistic-setMaxSampleAge command really set
+// max_sample_age limit correctly.
+TEST_F(StatsMgrTest, commandSetMaxSampleAge) {
+ StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
+
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("alpha"));
+ params->set("hours", Element::create(0));
+ params->set("minutes", Element::create(0));
+ params->set("seconds", Element::create(1));
+ params->set("milliseconds", Element::create(0));
+
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-setMaxSampleAge", params);
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
+
+ // Now check if time limit work
+ for (uint32_t i = 0; i < 10; ++i) {
+ if (i == 5) {
+ sleep(1); // wait one second to force exceeding the time limit
+ }
+ StatsMgr::instance().setValue("alpha", static_cast<int64_t>(i));
+ }
+
+ // It should be equal
+ EXPECT_EQ(StatsMgr::instance().getSize("alpha"), 5);
+}
+
+// Test checks if statistic-setMaxSampleAge is able to handle:
+// - a request without parameters
+// - a request without at least one of duration parameters
+// - a request with missing statistic name
+// - a request for non-existing statistic.
+TEST_F(StatsMgrTest, commandSetMaxSampleAgeNegative) {
+
+ // Case 1: a request without parameters
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-setMaxSampleAge", ElementPtr());
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 2: a request without at least one of duration parameters
+ ElementPtr params = Element::createMap();
+ params->set("seconds", Element::create(2));
+ params->set("milliseconds", Element::create(3));
+ rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-setMaxSampleAge", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 3: a request with missing statistic name
+ params = Element::createMap();
+ params->set("hours", Element::create(0));
+ params->set("minutes", Element::create(1));
+ params->set("seconds", Element::create(2));
+ params->set("milliseconds", Element::create(3));
+ rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-setMaxSampleAge", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 4: a request for non-existing statistic
+ params->set("name", Element::create("alpha"));
+ rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-setMaxSampleAge", params);
+ EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
+ rsp->str());
+}
+
+// This test checks whether statistic-setMaxSampleCount command really set
+// max_sample_count limit correctly.
+TEST_F(StatsMgrTest, commandSetMaxSampleCount) {
+ StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
+
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("alpha"));
+ params->set("max_samples", Element::create(15));
+
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-setMaxSampleCount", params);
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
+
+ // Now check if time limit work
+ for (uint32_t i = 0; i < 15; ++i) {
+ StatsMgr::instance().setValue("alpha", static_cast<int64_t>(i));
+ }
+
+ // It should be equal
+ EXPECT_EQ(StatsMgr::instance().getSize("alpha"), 15);
+}
+
+// Test checks if statistic-setMaxSampleAge is able to handle:
+// - a request without parameters
+// - a request without max_samples parameter
+// - a request with missing statistic name
+// - a request for non-existing statistic.
+TEST_F(StatsMgrTest, commandSetMaxSampleCountNegative) {
+
+ // Case 1: a request without parameters
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-setMaxSampleCount", ElementPtr());
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 2: a request without max_samples parameter
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("beta"));
+ rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-setMaxSampleCount", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 3: a request with missing statistic name
+ params = Element::createMap();
+ params->set("max_samples", Element::create(10));
+ rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-setMaxSampleCount", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 4: a request for non-existing statistic
+ params->set("name", Element::create("alpha"));
+ rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-setMaxSampleCount", params);
+ EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
+ rsp->str());
+}
+
};