mgmt: send FACE_EVENT_UP and FACE_EVENT_DOWN notifications
refs #3794
Change-Id: I98cc9db2652454d8fd09975b619433046e9bc7ca
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 0ce16c5..8a9bb1c 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -33,8 +33,6 @@
#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
-#include <ndn-cxx/mgmt/nfd/face-status.hpp>
-#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
#ifdef HAVE_UNIX_SOCKETS
#include "face/unix-stream-factory.hpp"
@@ -77,8 +75,13 @@
registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
m_postNotification = registerNotificationStream("events");
- m_faceAddConn = m_faceTable.afterAdd.connect(bind(&FaceManager::notifyAddFace, this, _1));
- m_faceRemoveConn = m_faceTable.beforeRemove.connect(bind(&FaceManager::notifyRemoveFace, this, _1));
+ m_faceAddConn = m_faceTable.afterAdd.connect([this] (const Face& face) {
+ connectFaceStateChangeSignal(face);
+ notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
+ });
+ m_faceRemoveConn = m_faceTable.beforeRemove.connect([this] (const Face& face) {
+ notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
+ });
}
void
@@ -493,13 +496,6 @@
.setNInBytes(counters.nInBytes)
.setNOutBytes(counters.nOutBytes);
- // Set Flag bits
- auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
- if (linkService != nullptr) {
- auto linkServiceOptions = linkService->getOptions();
- status.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
- }
-
return status;
}
@@ -513,26 +509,43 @@
.setFaceScope(face.getScope())
.setFacePersistency(face.getPersistency())
.setLinkType(face.getLinkType());
+
+ // Set Flag bits
+ auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
+ if (linkService != nullptr) {
+ auto linkServiceOptions = linkService->getOptions();
+ traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
+ }
}
void
-FaceManager::notifyAddFace(const Face& face)
+FaceManager::notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind)
{
ndn::nfd::FaceEventNotification notification;
- notification.setKind(ndn::nfd::FACE_EVENT_CREATED);
+ notification.setKind(kind);
collectFaceProperties(face, notification);
m_postNotification(notification.wireEncode());
}
void
-FaceManager::notifyRemoveFace(const Face& face)
+FaceManager::connectFaceStateChangeSignal(const Face& face)
{
- ndn::nfd::FaceEventNotification notification;
- notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED);
- collectFaceProperties(face, notification);
+ FaceId faceId = face.getId();
+ m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
+ [this, faceId] (face::FaceState oldState, face::FaceState newState) {
+ const Face& face = *m_faceTable.get(faceId);
- m_postNotification(notification.wireEncode());
+ if (newState == face::FaceState::UP) {
+ notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
+ }
+ else if (newState == face::FaceState::DOWN) {
+ notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
+ }
+ else if (newState == face::FaceState::CLOSED) {
+ m_faceStateChangeConn.erase(faceId);
+ }
+ });
}
void
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index 3a20dbd..c4a2c48 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -29,6 +29,7 @@
#include "nfd-manager-base.hpp"
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/mgmt/nfd/face-query-filter.hpp>
+#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
#include "face/face.hpp"
namespace nfd {
@@ -138,10 +139,10 @@
private: // NotificationStream
void
- notifyAddFace(const Face& face);
+ notifyFaceEvent(const Face& face, ndn::nfd::FaceEventKind kind);
void
- notifyRemoveFace(const Face& face);
+ connectFaceStateChangeSignal(const Face& face);
private: // configuration
void
@@ -168,6 +169,7 @@
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::map<std::string /*protocol*/, shared_ptr<ProtocolFactory>> m_factories;
FaceTable& m_faceTable;
+ std::map<FaceId, signal::ScopedConnection> m_faceStateChangeConn;
private:
ndn::mgmt::PostNotification m_postNotification;
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index 325b344..8a4907c 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -30,6 +30,7 @@
#include "nfd-manager-common-fixture.hpp"
#include "../face/dummy-face.hpp"
+#include "../face/dummy-transport.hpp"
#include <ndn-cxx/encoding/tlv.hpp>
#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
@@ -284,7 +285,7 @@
std::map<std::string, shared_ptr<TestChannel>> addedChannels;
size_t nEntries = 404;
- for (size_t i = 0 ; i < nEntries ; i ++) {
+ for (size_t i = 0; i < nEntries; i++) {
auto channel = factory->addChannel("test" + boost::lexical_cast<std::string>(i) + "://");
addedChannels[channel->getUri().toString()] = channel;
}
@@ -309,49 +310,113 @@
BOOST_AUTO_TEST_SUITE(Notifications)
-BOOST_AUTO_TEST_CASE(FaceEventNotification)
+BOOST_AUTO_TEST_CASE(FaceEventCreated)
{
- auto addedFace = addFace(); // trigger FACE_EVENT_CREATED notification
- BOOST_CHECK_NE(addedFace->getId(), -1);
- int64_t faceId = addedFace->getId();
+ auto face = addFace(); // trigger FACE_EVENT_CREATED notification
+ BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
+ FaceId faceId = face->getId();
+
+ BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 1);
// check notification
- {
- Block payload;
- ndn::nfd::FaceEventNotification notification;
- BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
- BOOST_CHECK_NO_THROW(payload = m_responses[0].getContent().blockFromValue());
- BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
- BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
- BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
- BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
- BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
- BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
- BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
- BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
- BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
- }
+ Block payload;
+ ndn::nfd::FaceEventNotification notification;
+ BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+ BOOST_CHECK_NO_THROW(payload = m_responses.back().getContent().blockFromValue());
+ BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+ BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+ BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
+ BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+ BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
+ BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
+ BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+ BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+ BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+ BOOST_CHECK_EQUAL(notification.getFlags(), 0x0);
+}
- addedFace->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
+BOOST_AUTO_TEST_CASE(FaceEventDownUp)
+{
+ auto face = addFace();
+ BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
+ FaceId faceId = face->getId();
+
+ // trigger FACE_EVENT_DOWN notification
+ dynamic_cast<face::tests::DummyTransport*>(face->getTransport())->setState(face::FaceState::DOWN);
advanceClocks(time::milliseconds(1), 10);
+ BOOST_CHECK_EQUAL(face->getState(), face::FaceState::DOWN);
// check notification
{
Block payload;
ndn::nfd::FaceEventNotification notification;
BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
- BOOST_CHECK_NO_THROW(payload = m_responses[1].getContent().blockFromValue());
+ BOOST_CHECK_NO_THROW(payload = m_responses.back().getContent().blockFromValue());
BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
- BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
+ BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DOWN);
BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
- BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
- BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+ BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
+ BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+ BOOST_CHECK_EQUAL(notification.getFlags(), 0x0);
}
- BOOST_CHECK_EQUAL(addedFace->getId(), face::INVALID_FACEID);
+
+ // trigger FACE_EVENT_UP notification
+ dynamic_cast<face::tests::DummyTransport*>(face->getTransport())->setState(face::FaceState::UP);
+ advanceClocks(time::milliseconds(1), 10);
+ BOOST_CHECK_EQUAL(face->getState(), face::FaceState::UP);
+
+ // check notification
+ {
+ Block payload;
+ ndn::nfd::FaceEventNotification notification;
+ BOOST_REQUIRE_EQUAL(m_responses.size(), 3);
+ BOOST_CHECK_NO_THROW(payload = m_responses.back().getContent().blockFromValue());
+ BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+ BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+ BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_UP);
+ BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+ BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
+ BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
+ BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+ BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+ BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+ BOOST_CHECK_EQUAL(notification.getFlags(), 0x0);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(FaceEventDestroyed)
+{
+ auto face = addFace();
+ BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
+ FaceId faceId = face->getId();
+
+ BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 1);
+
+ face->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
+ advanceClocks(time::milliseconds(1), 10);
+
+ // check notification
+ Block payload;
+ ndn::nfd::FaceEventNotification notification;
+ BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+ BOOST_CHECK_NO_THROW(payload = m_responses.back().getContent().blockFromValue());
+ BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+ BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+ BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
+ BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+ BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
+ BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
+ BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+ BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+ BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+ BOOST_CHECK_EQUAL(notification.getFlags(), 0x0);
+
+ BOOST_CHECK_EQUAL(face->getId(), face::INVALID_FACEID);
+ BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 0);
}
BOOST_AUTO_TEST_SUITE_END() // Notifications