[svn] commit: r3686 - in /branches/trac347: ./ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/bind10/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Dec 1 04:25:19 UTC 2010
Author: y-aharen
Date: Wed Dec 1 04:25:19 2010
New Revision: 3686
Log:
add query counters in b10-auth, interval timer class in asio_link and unittests (ticket #347)
Added:
branches/trac347/src/bin/auth/stats.cc
branches/trac347/src/bin/auth/stats.h
Modified:
branches/trac347/ChangeLog
branches/trac347/src/bin/auth/Makefile.am
branches/trac347/src/bin/auth/asio_link.cc
branches/trac347/src/bin/auth/asio_link.h
branches/trac347/src/bin/auth/auth.spec.pre.in
branches/trac347/src/bin/auth/auth_srv.cc
branches/trac347/src/bin/auth/auth_srv.h
branches/trac347/src/bin/auth/benchmarks/Makefile.am
branches/trac347/src/bin/auth/main.cc
branches/trac347/src/bin/auth/tests/Makefile.am
branches/trac347/src/bin/auth/tests/asio_link_unittest.cc
branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac347/src/bin/bind10/bind10.py.in
Modified: branches/trac347/ChangeLog
==============================================================================
--- branches/trac347/ChangeLog (original)
+++ branches/trac347/ChangeLog Wed Dec 1 04:25:19 2010
@@ -1,3 +1,10 @@
+ TBD. [func] y-aharen
+ src/bin/auth: Added a feature to count query and send counter
+ values to b10-stats periodically. To support it, added wrapping
+ class of asio::deadline_timer to use as interval timer.
+ Added a command 'sendstats' to send counter values at once.
+ (Trac #347, svn rxxxx)
+
122. [func] stephen
src/bin/bind10: Added configuration options to Boss to determine
whether to start the authoritative server, recursive server (or
Modified: branches/trac347/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac347/src/bin/auth/Makefile.am (original)
+++ branches/trac347/src/bin/auth/Makefile.am Wed Dec 1 04:25:19 2010
@@ -58,6 +58,7 @@
b10_auth_SOURCES = auth_srv.cc auth_srv.h
b10_auth_SOURCES += change_user.cc change_user.h
b10_auth_SOURCES += common.h
+b10_auth_SOURCES += stats.cc stats.h
b10_auth_SOURCES += main.cc
b10_auth_LDADD = $(top_builddir)/src/lib/datasrc/libdatasrc.la
b10_auth_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
Modified: branches/trac347/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac347/src/bin/auth/asio_link.cc (original)
+++ branches/trac347/src/bin/auth/asio_link.cc Wed Dec 1 04:25:19 2010
@@ -666,4 +666,78 @@
impl_->tcp6_server_->setCallBack(&impl_->callback_);
}
}
-}
+
+class IntervalTimerImpl {
+private:
+ // prohibit copy to avoid the function be called twice
+ IntervalTimerImpl(const IntervalTimerImpl& source);
+ IntervalTimerImpl& operator=(const IntervalTimerImpl& source);
+public:
+ IntervalTimerImpl(asio::io_service& io_service);
+ ~IntervalTimerImpl();
+ bool setupTimer(const IntervalTimer::Callback& cbfunc,
+ const uint32_t interval);
+ void callback(const asio::error_code& error);
+private:
+ void updateTimer();
+ IntervalTimer::Callback cbfunc_;
+ // interval in seconds
+ uint32_t interval_;
+ asio::deadline_timer timer_;
+};
+
+IntervalTimerImpl::IntervalTimerImpl(asio::io_service& io_service) :
+ timer_(io_service)
+{}
+
+IntervalTimerImpl::~IntervalTimerImpl() {
+ timer_.cancel();
+}
+
+bool
+IntervalTimerImpl::setupTimer(const IntervalTimer::Callback& cbfunc,
+ const uint32_t interval)
+{
+ // interval value must be positive
+ assert(interval > 0);
+ cbfunc_ = cbfunc;
+ interval_ = interval;
+ // start timer
+ updateTimer();
+ return (true);
+}
+
+void
+IntervalTimerImpl::updateTimer() {
+ // update expire time (current time + interval_)
+ timer_.expires_from_now(boost::posix_time::seconds(interval_));
+ // restart timer
+ timer_.async_wait(boost::bind(&IntervalTimerImpl::callback, this, _1));
+}
+
+void
+IntervalTimerImpl::callback(const asio::error_code& cancelled) {
+ assert(!cbfunc_.empty());
+ // skip function call in case the timer was cancelled
+ if (!cancelled) {
+ cbfunc_();
+ // restart timer
+ updateTimer();
+ }
+}
+
+IntervalTimer::IntervalTimer(asio::io_service& io_service) {
+ impl_ = new IntervalTimerImpl(io_service);
+}
+
+IntervalTimer::~IntervalTimer() {
+ delete impl_;
+}
+
+bool
+IntervalTimer::setupTimer(const Callback& cbfunc,
+ const uint32_t interval)
+{
+ return (impl_->setupTimer(cbfunc, interval));
+}
+}
Modified: branches/trac347/src/bin/auth/asio_link.h
==============================================================================
--- branches/trac347/src/bin/auth/asio_link.h (original)
+++ branches/trac347/src/bin/auth/asio_link.h Wed Dec 1 04:25:19 2010
@@ -89,6 +89,7 @@
namespace asio_link {
class IOServiceImpl;
+struct IntervalTimerImpl;
/// \brief An exception that is thrown if an error occurs within the IO
/// module. This is mainly intended to be a wrapper exception class for
@@ -444,6 +445,46 @@
private:
IOServiceImpl* impl_;
};
+
+/// \brief The \c IntervalTimer class is a wrapper for the ASIO \c deadline_timer
+/// class.
+///
+/// This class is implemented to use boost::deadline_timer as interval timer.
+/// Copy of this class is prohibited not to call the callback function twice.
+class IntervalTimer {
+public:
+ /// \name The type of timer callback function
+ typedef boost::function<void(void)> Callback;
+
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private, making this class non-copyable.
+ //@{
+private:
+ IntervalTimer(const IntervalTimer& source);
+ IntervalTimer& operator=(const IntervalTimer& source);
+public:
+ /// \brief The constructor with asio::io_service.
+ ///
+ /// \param io_service A reference to an instance of asio::io_service
+ IntervalTimer(asio::io_service& io_service);
+ /// \brief The destructor.
+ ~IntervalTimer();
+ //@}
+
+ /// \brief Register timer callback function
+ ///
+ /// \param cbfunc A reference to a function to call back
+ /// when the timer is expired
+ /// \param interval Interval in seconds
+ ///
+ /// \return \c true on success
+ bool setupTimer(const Callback& cbfunc, const uint32_t interval);
+private:
+ IntervalTimerImpl* impl_;
+};
} // asio_link
#endif // __ASIO_LINK_H
Modified: branches/trac347/src/bin/auth/auth.spec.pre.in
==============================================================================
--- branches/trac347/src/bin/auth/auth.spec.pre.in (original)
+++ branches/trac347/src/bin/auth/auth.spec.pre.in Wed Dec 1 04:25:19 2010
@@ -14,6 +14,11 @@
"command_name": "shutdown",
"command_description": "Shut down authoritative DNS server",
"command_args": []
+ },
+ {
+ "command_name": "sendstats",
+ "command_description": "Send statistics data to b10-stats at once",
+ "command_args": []
}
]
}
Modified: branches/trac347/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac347/src/bin/auth/auth_srv.cc (original)
+++ branches/trac347/src/bin/auth/auth_srv.cc Wed Dec 1 04:25:19 2010
@@ -128,10 +128,13 @@
AuthSrv::AuthSrv(const bool use_cache, AbstractXfroutClient& xfrout_client) :
impl_(new AuthSrvImpl(use_cache, xfrout_client))
-{}
+{
+ counter = new statistics::Counter(impl_->verbose_mode_);
+}
AuthSrv::~AuthSrv() {
delete impl_;
+ delete counter;
}
namespace {
@@ -214,6 +217,11 @@
impl_->config_session_ = config_session;
}
+void
+AuthSrv::setStatsSession(AbstractSession* stats_session) {
+ counter->setStatsSession(stats_session);
+}
+
ModuleCCSession*
AuthSrv::getConfigSession() const {
return (impl_->config_session_);
@@ -264,6 +272,19 @@
if (impl_->verbose_mode_) {
cerr << "[b10-auth] received a message:\n" << message.toText() << endl;
+ }
+
+ // increment Query Counter
+ if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
+ counter->inc(statistics::Counter::COUNTER_UDP);
+ } else if (io_message.getSocket().getProtocol() == IPPROTO_TCP) {
+ counter->inc(statistics::Counter::COUNTER_TCP);
+ } else {
+ // unknown protocol
+ if (impl_->verbose_mode_) {
+ cerr << "[b10-auth] Unknown protocol: " <<
+ io_message.getSocket().getProtocol() << endl;
+ }
}
// Perform further protocol-level validation.
@@ -543,3 +564,10 @@
return (isc::config::createAnswer(1, error.what()));
}
}
+
+asio_link::IntervalTimer::Callback
+AuthSrv::getStatsCallback() {
+ // just invoke statistics::Counter::getStatsCallback()
+ // and return its return value
+ return (counter->getCallback());
+}
Modified: branches/trac347/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac347/src/bin/auth/auth_srv.h (original)
+++ branches/trac347/src/bin/auth/auth_srv.h Wed Dec 1 04:25:19 2010
@@ -21,6 +21,12 @@
#include <cc/data.h>
#include <config/ccsession.h>
+
+/// for the typedef of asio_link::IntervalTimer::Callback
+#include <auth/asio_link.h>
+
+// for class statistics::Counter
+#include <auth/stats.h>
namespace isc {
namespace dns {
@@ -199,8 +205,28 @@
/// is shutdown.
///
void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
+
+ /// \brief Set the communication session with Statistics.
+ ///
+ void setStatsSession(isc::cc::AbstractSession* stats_session);
+
+ /// \brief Return the function that sends statistics information
+ /// to Statistics module.
+ ///
+ /// This function returns the return value of
+ /// statistics::Counter::getCallback().
+ ///
+ /// \return \c boost::function which contains the procedure
+ /// to send statistics.
+ asio_link::IntervalTimer::Callback getStatsCallback();
private:
AuthSrvImpl* impl_;
+
+ // TODO: consider where to put the counter.
+ // Currently, count-up is in AuthSrv::processMessage.
+ // In the future, count-up will be in AuthSrvImpl::process*Query
+ // and this declaration will be moved into AuthSrvImpl.
+ statistics::Counter *counter;
};
#endif // __AUTH_SRV_H
Modified: branches/trac347/src/bin/auth/benchmarks/Makefile.am
==============================================================================
--- branches/trac347/src/bin/auth/benchmarks/Makefile.am (original)
+++ branches/trac347/src/bin/auth/benchmarks/Makefile.am Wed Dec 1 04:25:19 2010
@@ -9,6 +9,7 @@
noinst_PROGRAMS = query_bench
query_bench_SOURCES = query_bench.cc
query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
+query_bench_SOURCES += ../stats.h ../stats.cc
query_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
query_bench_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
Modified: branches/trac347/src/bin/auth/main.cc
==============================================================================
--- branches/trac347/src/bin/auth/main.cc (original)
+++ branches/trac347/src/bin/auth/main.cc Wed Dec 1 04:25:19 2010
@@ -59,6 +59,10 @@
const string PROGRAM = "Auth";
const char* DNSPORT = "5300";
+// Note: this value must be greater than 0.
+// TODO: make it configurable via command channel.
+const uint32_t STATS_SEND_INTERVAL_SEC = 60;
+
/* need global var for config/command handlers.
* todo: turn this around, and put handlers in the authserver
* class itself? */
@@ -81,6 +85,13 @@
answer = createAnswer(0, args);
} else if (command == "shutdown") {
io_service->stop();
+ } else if (command == "sendstats") {
+ if (verbose_mode) {
+ cerr << "[b10-auth] command 'sendstats' received" << endl;
+ }
+ if (auth_server != NULL) {
+ auth_server->getStatsCallback()();
+ }
}
return (answer);
@@ -154,7 +165,10 @@
// XXX: we should eventually pass io_service here.
Session* cc_session = NULL;
Session* xfrin_session = NULL;
+ Session* stats_session = NULL;
+ asio_link::IntervalTimer* itimer = NULL;
bool xfrin_session_established = false; // XXX (see Trac #287)
+ bool stats_session_established = false; // XXX (see Trac #287)
ModuleCCSession* config_session = NULL;
string xfrout_socket_path;
if (getenv("B10_FROM_BUILD") != NULL) {
@@ -209,14 +223,29 @@
xfrin_session_established = true;
cout << "[b10-auth] Xfrin session channel established." << endl;
+ stats_session = new Session(io_service->get_io_service());
+ cout << "[b10-auth] Stats session channel created." << endl;
+ stats_session->establish(NULL);
+ stats_session_established = true;
+ cout << "[b10-auth] Stats session channel established." << endl;
+
// XXX: with the current interface to asio_link we have to create
// auth_server before io_service while Session needs io_service.
// In a next step of refactoring we should make asio_link independent
// from auth_server, and create io_service, auth_server, and
// sessions in that order.
auth_server->setXfrinSession(xfrin_session);
+ auth_server->setStatsSession(stats_session);
auth_server->setConfigSession(config_session);
auth_server->updateConfig(ElementPtr());
+
+ // create interval timer instance
+ itimer = new asio_link::IntervalTimer(io_service->get_io_service());
+ // set up interval timer
+ // register function to send statistics with interval
+ itimer->setupTimer(auth_server->getStatsCallback(),
+ STATS_SEND_INTERVAL_SEC);
+ cout << "[b10-auth] Interval timer set to send stats." << endl;
cout << "[b10-auth] Server started." << endl;
io_service->run();
@@ -225,10 +254,16 @@
ret = 1;
}
+ if (stats_session_established) {
+ stats_session->disconnect();
+ }
+
if (xfrin_session_established) {
xfrin_session->disconnect();
}
+ delete itimer;
+ delete stats_session;
delete xfrin_session;
delete config_session;
delete cc_session;
Modified: branches/trac347/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac347/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac347/src/bin/auth/tests/Makefile.am Wed Dec 1 04:25:19 2010
@@ -22,6 +22,7 @@
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES += ../change_user.h ../change_user.cc
+run_unittests_SOURCES += ../stats.h ../stats.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += change_user_unittest.cc
run_unittests_SOURCES += asio_link_unittest.cc
Modified: branches/trac347/src/bin/auth/tests/asio_link_unittest.cc
==============================================================================
--- branches/trac347/src/bin/auth/tests/asio_link_unittest.cc (original)
+++ branches/trac347/src/bin/auth/tests/asio_link_unittest.cc Wed Dec 1 04:25:19 2010
@@ -252,6 +252,15 @@
callback_data_.size(),
expected_data, expected_datasize);
}
+ void doTimerTest(asio_link::IntervalTimer* itimer) {
+ // interval timer test
+ // set test_obj_->timerCallBack() as callback function
+ // and check that the function was called
+ timer_called_ = false;
+ EXPECT_TRUE(itimer->setupTimer(TimerCallBack(this), 1));
+ io_service_->run();
+ EXPECT_TRUE(timer_called_);
+ }
private:
class ASIOCallBack : public std::unary_function<IOMessage, void> {
public:
@@ -273,12 +282,27 @@
io_message.getDataSize());
io_service_->stop();
}
+private:
+ class TimerCallBack : public std::unary_function<void, void> {
+ public:
+ TimerCallBack(ASIOLinkTest* test_obj) : test_obj_(test_obj) {}
+ void operator()(void) const {
+ test_obj_->timerCallBack();
+ }
+ private:
+ ASIOLinkTest* test_obj_;
+ };
+ void timerCallBack() {
+ timer_called_ = true;
+ io_service_->stop();
+ }
protected:
IOService* io_service_;
int callback_protocol_;
int callback_native_;
string callback_address_;
vector<uint8_t> callback_data_;
+ bool timer_called_;
int sock_;
private:
struct addrinfo* res_;
@@ -354,4 +378,12 @@
EXPECT_THROW(sendTCP(AF_INET6), IOError);
}
-}
+TEST_F(ASIOLinkTest, startIntervalTimer) {
+ // Create asio_link::IntervalTimer and setup.
+ // Then run IOService and test if the callback function is called.
+ setIOService(false, false);
+ asio_link::IntervalTimer *itimer = new asio_link::IntervalTimer(io_service_->get_io_service());
+ doTimerTest(itimer);
+ delete itimer;
+}
+}
Modified: branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc Wed Dec 1 04:25:19 2010
@@ -44,6 +44,7 @@
using namespace isc::data;
using namespace isc::xfr;
using namespace asio_link;
+using namespace statistics;
namespace {
const char* const CONFIG_TESTDB =
@@ -120,15 +121,18 @@
qclass(RRClass::IN()), qtype(RRType::A()),
io_message(NULL), endpoint(NULL), request_obuffer(0),
request_renderer(request_obuffer),
- response_obuffer(0), response_renderer(response_obuffer)
+ response_obuffer(0), response_renderer(response_obuffer),
+ counter(counter_verbose)
{
server.setXfrinSession(¬ify_session);
+ server.setStatsSession(&stats_session);
}
~AuthSrvTest() {
delete io_message;
delete endpoint;
}
MockSession notify_session;
+ MockSession stats_session;
MockXfroutClient xfrout;
AuthSrv server;
Message request_message;
@@ -145,6 +149,12 @@
OutputBuffer response_obuffer;
MessageRenderer response_renderer;
vector<uint8_t> data;
+ // for Counter unittest
+ // TODO: consider where to put Counter
+ // AuthSrvTest is now includes a test for Counter
+ // In future make a test class CounterTest
+ bool counter_verbose;
+ Counter counter;
void createDataFromFile(const char* const datafile, int protocol);
void createRequestMessage(const Opcode& opcode, const Name& request_name,
@@ -767,4 +777,52 @@
server.setCacheSlots(0);
EXPECT_EQ(00, server.getCacheSlots());
}
-}
+
+TEST_F(AuthSrvTest, statsCallback) {
+ // getStatsCallback() test
+ // expect returning a valid function
+ asio_link::IntervalTimer::Callback cbFunc;
+ cbFunc = server.getStatsCallback();
+ EXPECT_FALSE(cbFunc.empty());
+}
+
+TEST_F(AuthSrvTest, sendStatsWithoutSession) {
+ // to cover the code path in case the stats session is not set
+ // expect to put an error message
+ server.setStatsSession(NULL);
+ bool verbose = server.getVerbose();
+ server.setVerbose(true);
+ server.getStatsCallback()();
+ server.setVerbose(verbose);
+}
+
+//
+// statistics::Counter unittest
+
+TEST_F(AuthSrvTest, counter_incUDP) {
+ counter.inc(Counter::COUNTER_UDP);
+}
+
+TEST_F(AuthSrvTest, counter_incTCP) {
+ counter.inc(Counter::COUNTER_TCP);
+}
+
+TEST_F(AuthSrvTest, counter_incUnknown) {
+ EXPECT_THROW(counter.inc(Counter::COUNTER_TYPES), std::out_of_range);
+}
+
+TEST_F(AuthSrvTest, counter_getCallback) {
+ // getCallback() test
+ // expect returning a valid function
+ asio_link::IntervalTimer::Callback cbFunc;
+ cbFunc = counter.getCallback();
+ EXPECT_FALSE(cbFunc.empty());
+}
+
+TEST_F(AuthSrvTest, counter_sendStatsWithSession) {
+ // Test the function to send statistics information to b10-stats
+ // expect to run without throwing any exception
+ counter.setStatsSession(&stats_session);
+ counter.getCallback()();
+}
+}
Modified: branches/trac347/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac347/src/bin/bind10/bind10.py.in (original)
+++ branches/trac347/src/bin/bind10/bind10.py.in Wed Dec 1 04:25:19 2010
@@ -544,10 +544,10 @@
self.cc_session.group_sendmsg(cmd, "ConfigManager", "ConfigManager")
self.cc_session.group_sendmsg(cmd, "Auth", "Auth")
self.cc_session.group_sendmsg(cmd, "Recurse", "Recurse")
+ self.cc_session.group_sendmsg(cmd, "Stats", "Stats")
self.cc_session.group_sendmsg(cmd, "Xfrout", "Xfrout")
self.cc_session.group_sendmsg(cmd, "Xfrin", "Xfrin")
self.cc_session.group_sendmsg(cmd, "Zonemgr", "Zonemgr")
- self.cc_session.group_sendmsg(cmd, "Boss", "Stats")
def stop_process(self, process):
"""Stop the given process, friendly-like."""
More information about the bind10-changes
mailing list