/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @param [out] audit_entries Reference to the container where fetched audit
/// entries will be inserted.
void getRecentAuditEntries(const int index,
<< audit_entry->getObjectId() << ", "
<< static_cast<int>(audit_entry->getModificationType()) << ", "
<< audit_entry->getModificationTime() << ", "
- << audit_entry->getEntryId() << ", "
+ << audit_entry->getModificationId() << ", "
<< audit_entry->getLogMessage()
<< std::endl;
}
<< audit_entry->getObjectId() << ", "
<< static_cast<int>(audit_entry->getModificationType()) << ", "
<< audit_entry->getModificationTime() << ", "
- << audit_entry->getEntryId() << ", "
+ << audit_entry->getModificationId() << ", "
<< audit_entry->getLogMessage()
<< std::endl;
}
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/shared_ptr.hpp>
/// entries with later modification time than stored. That way the
/// server queries only for the audit entries it hasn't fetched yet.
/// In the case two (or more) successive audit entries have the same
-/// modification time the strictly increasing id is used.
+/// modification time the strictly increasing modification id is used.
///
/// When the modification type of the entry is set to
/// @c AuditEntry::ModificationType::DELETE, the corresponding
/// @brief Returns entry id.
///
/// @return Identifier of the entry.
- uint64_t getEntryId() const {
+ uint64_t getModificationId() const {
return (id_);
}
/// @brief Tag used to access index by modification time.
struct AuditEntryModificationTimeIdTag { };
+/// @brief Tag used to access index by object id.
+struct AuditEntryObjectIdTag { };
+
/// @brief Multi index container holding @c AuditEntry instances.
///
/// This container provides indexes to access the audit entries
boost::multi_index::const_mem_fun<
AuditEntry,
uint64_t,
- &AuditEntry::getEntryId
+ &AuditEntry::getModificationId
>
>
+ >,
+
+ // Third index allows for accessing by the object id.
+ boost::multi_index::hashed_non_unique<
+ boost::multi_index::tag<AuditEntryObjectIdTag>,
+ boost::multi_index::const_mem_fun<
+ AuditEntry,
+ uint64_t,
+ &AuditEntry::getObjectId
+ >
>
>
> AuditEntryCollection;
EXPECT_EQ(10, audit_entry->getObjectId());
EXPECT_EQ(AuditEntry::ModificationType::DELETE, audit_entry->getModificationType());
EXPECT_EQ(fixedTime(), audit_entry->getModificationTime());
- EXPECT_EQ(123, audit_entry->getEntryId());
+ EXPECT_EQ(123, audit_entry->getModificationId());
EXPECT_EQ("deleted subnet 10", audit_entry->getLogMessage());
}
EXPECT_EQ(123, audit_entry->getObjectId());
EXPECT_EQ(AuditEntry::ModificationType::CREATE, audit_entry->getModificationType());
EXPECT_TRUE(almostEqualTime(audit_entry->getModificationTime()));
- EXPECT_EQ(234, audit_entry->getEntryId());
+ EXPECT_EQ(234, audit_entry->getModificationId());
EXPECT_TRUE(audit_entry->getLogMessage().empty());
}
}
return (false);
}
+ /// @brief Checks if the returned results range contains an @c AuditEntry
+ /// with a given object and modification types, and object identifier.
+ ///
+ /// @param object_type expected object type.
+ /// @param object_id expected object id.
+ /// @param modification_type expected modification type.
+ /// @param begin beginning of the results range to be examined.
+ /// @param end end of the results range to be examined.
+ template<typename Iterator>
+ bool includes(const std::string& object_type, const uint64_t object_id,
+ const AuditEntry::ModificationType& modification_type,
+ Iterator begin, Iterator end) {
+ // Iterate over the results range and look for the entry.
+ for (auto it = begin; it != end; ++it) {
+ if (((*it)->getObjectType() == object_type) &&
+ ((*it)->getObjectId() == object_id) &&
+ ((*it)->getModificationType() == modification_type)) {
+ // Entry found.
+ return (true);
+ }
+ }
+
+ // Entry not found.
+ return (false);
+ }
+
/// @brief Audit entries used in the tests.
AuditEntryCollection audit_entries_;
EXPECT_TRUE(includes("dhcp4_subnet", 1000, lb, mod_time_idx.end()));
EXPECT_TRUE(includes("dhcp4_shared_network", 1, lb, mod_time_idx.end()));
EXPECT_TRUE(includes("dhcp4_option", 15, lb, mod_time_idx.end()));
+
+ // Check the order is time first, id after.
+ create("dhcp4_subnet", 1000, AuditEntry::ModificationType::UPDATE,
+ diffTime(-8), 200, "updated subnet 1000");
+ lb = mod_time_idx.lower_bound(mod);
+ ASSERT_EQ(4, std::distance(lb, mod_time_idx.end()));
+ EXPECT_TRUE(includes("dhcp4_subnet", 120, lb, mod_time_idx.end()));
+ EXPECT_TRUE(includes("dhcp4_subnet", 1000, lb, mod_time_idx.end()));
+ EXPECT_TRUE(includes("dhcp4_shared_network", 1, lb, mod_time_idx.end()));
+ EXPECT_TRUE(includes("dhcp4_option", 15, lb, mod_time_idx.end()));
+}
+
+// Checks that entries can be found by object id.
+TEST_F(AuditEntryCollectionTest, getByObjectId) {
+ const auto& object_id_idx = audit_entries_.get<AuditEntryObjectIdTag>();
+
+ // Search for object id 10.
+ auto range = object_id_idx.equal_range(10);
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ EXPECT_TRUE(includes("dhcp4_subnet", 10, range.first, range.second));
+
+ // Add another entry.
+ create("dhcp4_subnet", 10, AuditEntry::ModificationType::UPDATE,
+ diffTime(0), 111, "updated subnet 10");
+
+ // Now search should return two entries.
+ range = object_id_idx.equal_range(10);
+ ASSERT_EQ(2, std::distance(range.first, range.second));
+ EXPECT_TRUE(includes("dhcp4_subnet", 10,
+ AuditEntry::ModificationType::CREATE,
+ range.first, range.second));
+ EXPECT_TRUE(includes("dhcp4_subnet", 10,
+ AuditEntry::ModificationType::UPDATE,
+ range.first, range.second));
}
}
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::BackendSelector& backend_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::BackendSelector& backend_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
/// @param modification_time Timestamp being a lower limit for the returned
/// result set, i.e. entries later than specified time are returned.
/// @param modification_id Identifier being a lower limit for the returned
- /// result set, used when two (or more) entries have modification_time.
+ /// result set, used when two (or more) entries have the same
+ /// modification_time.
/// @return Collection of audit entries.
virtual db::AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector& server_selector,
// latest entry.
const auto& index = audit_entries.get<db::AuditEntryModificationTimeIdTag>();
last_audit_entry_time_ = (*index.rbegin())->getModificationTime();
- last_audit_entry_id_ = (*index.rbegin())->getEntryId();
+ last_audit_entry_id_ = (*index.rbegin())->getModificationId();
}
/// @brief Stores the most recent audit entry timestamp.