+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stats/context.h>
+#include <map>
+
+namespace isc {
+namespace stats {
+
+ObservationPtr StatContext::get(const std::string& name) {
+ std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
+ if (obs == stats_.end()) {
+ return (ObservationPtr());
+ } else {
+ return (obs->second);
+ }
+}
+
+void StatContext::add(const ObservationPtr& obs) {
+ std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
+ if (obs == stats_.end()) {
+ stats_.insert(make_pair(obs->getName() ,obs));
+ } else {
+ isc_throw(InvalidStatType, "Statistic named " << obs->getName()
+ << " already exists.");
+ }
+
+}
+
+bool StatContext::del(const std::string& name) {
+ std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
+ if (obs == stats_.end()) {
+ return (false);
+ } else {
+ stats_.erase(obs);
+ return (true);
+ }
+}
+
+};
+};
-
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
#ifndef CONTEXT_H
#define CONTEXT_H
#include <stats/observation.h>
#include <boost/shared_ptr.hpp>
+#include <string>
namespace isc {
namespace stats {
+/// @brief Exception indicating that a given statistic is duplicated.
+class DuplicateStat : public Exception {
+public:
+ DuplicateStat(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+/// @brief Statistics context
+///
+/// Statistics context is essentially a container used to group statistics
+/// related to a given context together. Two examples of such contexts are
+/// all statistics related to a given subnet or all statistics related to a
+/// given network interface.
class StatContext {
public:
- std::map<std::string, ObservationPtr> stats;
+
+ /// @brief attempts to get an observation
+ /// @param name name of the statistic
+ /// @return appropriate Observation object (or NULL)
+ ObservationPtr get(const std::string& name);
+
+ /// @brief Adds a new observation
+ /// @param obs observation to be added
+ /// @throw DuplicateStat if an observation with the same name exists already
+ void add(const ObservationPtr& obs);
+
+ /// @brief Attempts to delete an observation
+ /// @param name name of the observation to be deleted
+ /// @return true if successful, false if no such statistic was found
+ bool del(const std::string& name);
+
+ /// @brief Statistics container
+ ///
+ /// It is public to allow various operations that require iterating over
+ /// all elements. In particular, two operations (setting all stats to 0;
+ /// reporting all stats) will take advantage of this. Alternatively, we
+ /// could make it protected and then return a pointer to it, but that
+ /// would defeat the purpose of the hermetization in the first place.
+ std::map<std::string, ObservationPtr> stats_;
};
- typedef boost::shared_ptr<StatContext> StatContextPtr;
+typedef boost::shared_ptr<StatContext> StatContextPtr;
};
};
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <stats/context.h>
+#include <gtest/gtest.h>
+
+using namespace isc::stats;
+
+// Basic test that checks get, add, del methods
+TEST(ContextTest, basic) {
+
+ // Let's create a couple observations. Using floating point,
+ // as they're easiest to initialize.
+ ObservationPtr a(new Observation("alpha", 1.11));
+ ObservationPtr b(new Observation("beta", 2.22));
+ ObservationPtr c(new Observation("gamma", 3.33));
+
+ // Context where we will store the observations.
+ StatContext ctx;
+
+ // By default the context does not hold any statistics.
+ EXPECT_EQ(0, ctx.stats_.size());
+ EXPECT_TRUE(ctx.stats_.empty());
+
+ // It should be possible to add 'a' statistic
+ EXPECT_NO_THROW(ctx.add(a));
+
+ // We can't add a duplicate.
+ EXPECT_THROW(ctx.add(a), DuplicateStat);
+
+ // It should be ok to add other statistics
+ EXPECT_NO_THROW(ctx.add(b));
+ EXPECT_NO_THROW(ctx.add(c));
+
+ // By now we should have 3 statistics recorded
+ EXPECT_EQ(3, ctx.stats_.size());
+ EXPECT_FALSE(ctx.stats_.empty());
+
+ // Let's try to retrieve them
+ ObservationPtr from_ctx;
+ EXPECT_NO_THROW(from_ctx = ctx.get("alpha"));
+ ASSERT_TRUE(from_ctx);
+ EXPECT_EQ(a->getJSON()->str(), from_ctx->getJSON()->str());
+
+ EXPECT_NO_THROW(from_ctx = ctx.get("beta"));
+ ASSERT_TRUE(from_ctx);
+ EXPECT_EQ(b->getJSON()->str(), from_ctx->getJSON()->str());
+
+ EXPECT_NO_THROW(from_ctx = ctx.get("gamma"));
+ ASSERT_TRUE(from_ctx);
+ EXPECT_EQ(c->getJSON()->str(), from_ctx->getJSON()->str());
+
+ // Let's try to retrieve non-existing stat
+ EXPECT_NO_THROW(from_ctx = ctx.get("delta"));
+ EXPECT_FALSE(from_ctx);
+
+ // Now delete one of the stats...
+ EXPECT_TRUE(ctx.del("beta"));
+
+ // ... and check that it's really gone.
+ EXPECT_FALSE(ctx.get("beta"));
+
+ // Attempt to delete non-existing stat should fail.
+ EXPECT_FALSE(ctx.del("beta"));
+}
+