publisher: implement routing table dataset publisher

refs: #3631, #3634

Change-Id: I7e961fdd0857690bee65d2bdfa4cf3de90ccac06
diff --git a/src/publisher/lsdb-dataset-interest-handler.cpp b/src/publisher/dataset-interest-handler.cpp
similarity index 66%
rename from src/publisher/lsdb-dataset-interest-handler.cpp
rename to src/publisher/dataset-interest-handler.cpp
index 53cdfbc..efd76f8 100644
--- a/src/publisher/lsdb-dataset-interest-handler.cpp
+++ b/src/publisher/dataset-interest-handler.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2018,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -19,66 +19,56 @@
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  **/
 
-/*! \file lsdb-dataset-interest-handler.cpp
-
-  This file details a class that is used by NLSRC and other command-line
-  tools to examine the state of NLSR. This system is not designed to
-  be used by routers to publish data to each other.
- */
-
-#include "lsdb-dataset-interest-handler.hpp"
-
+#include "dataset-interest-handler.hpp"
 #include "nlsr.hpp"
 #include "tlv/lsdb-status.hpp"
 #include "logger.hpp"
 
-#include <ndn-cxx/face.hpp>
 #include <ndn-cxx/mgmt/nfd/control-response.hpp>
 #include <ndn-cxx/util/regex.hpp>
 
 namespace nlsr {
 
-INIT_LOGGER("LsdbDatasetInterestHandler");
+INIT_LOGGER("DatasetInterestHandler");
 
 const ndn::PartialName ADJACENCIES_DATASET = ndn::PartialName("lsdb/adjacencies");
 const ndn::PartialName COORDINATES_DATASET = ndn::PartialName("lsdb/coordinates");
 const ndn::PartialName NAMES_DATASET = ndn::PartialName("lsdb/names");
-const ndn::PartialName LISTS_DATASET = ndn::PartialName("lsdb/list");
+const ndn::PartialName RT_DATASET = ndn::PartialName("routing-table");
 
-LsdbDatasetInterestHandler::LsdbDatasetInterestHandler(Lsdb& lsdb,
-                                                       ndn::mgmt::Dispatcher& localHostDispatcher,
-                                                       ndn::mgmt::Dispatcher& routerNameDispatcher,
-                                                       ndn::Face& face,
-                                                       ndn::KeyChain& keyChain)
+DatasetInterestHandler::DatasetInterestHandler(const Lsdb& lsdb,
+                                               const RoutingTable& rt,
+                                               ndn::mgmt::Dispatcher& dispatcher,
+                                               const ndn::Face& face,
+                                               const ndn::KeyChain& keyChain)
   : m_lsdb(lsdb)
-  , m_localhostDispatcher(localHostDispatcher)
-  , m_routerNameDispatcher(routerNameDispatcher)
+  , m_dispatcher(dispatcher)
+  , m_routingTableEntries(rt.getRoutingTableEntry())
+  , m_dryRoutingTableEntries(rt.getDryRoutingTableEntry())
 {
-  NLSR_LOG_DEBUG("Setting dispatcher for lsdb status dataset:");
-  setDispatcher(m_localhostDispatcher);
-  setDispatcher(m_routerNameDispatcher);
+  setDispatcher(m_dispatcher);
 }
 
 void
-LsdbDatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
+DatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
 {
   dispatcher.addStatusDataset(ADJACENCIES_DATASET,
     ndn::mgmt::makeAcceptAllAuthorization(),
-    std::bind(&LsdbDatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
+    std::bind(&DatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
   dispatcher.addStatusDataset(COORDINATES_DATASET,
     ndn::mgmt::makeAcceptAllAuthorization(),
-    std::bind(&LsdbDatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
+    std::bind(&DatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
   dispatcher.addStatusDataset(NAMES_DATASET,
     ndn::mgmt::makeAcceptAllAuthorization(),
-    std::bind(&LsdbDatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
-  dispatcher.addStatusDataset(LISTS_DATASET,
+    std::bind(&DatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
+  dispatcher.addStatusDataset(RT_DATASET,
     ndn::mgmt::makeAcceptAllAuthorization(),
-    std::bind(&LsdbDatasetInterestHandler::publishAllStatus, this, _1, _2, _3));
+    std::bind(&DatasetInterestHandler::publishRtStatus, this, _1, _2, _3));
 }
 
 void
-LsdbDatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
-                                             ndn::mgmt::StatusDatasetContext& context)
+DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                         ndn::mgmt::StatusDatasetContext& context)
 {
   NLSR_LOG_DEBUG("Received interest:  " << interest);
 
@@ -104,8 +94,8 @@
 }
 
 void
-LsdbDatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
-                                                    ndn::mgmt::StatusDatasetContext& context)
+DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                                ndn::mgmt::StatusDatasetContext& context)
 {
   auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
                                  std::list<CoordinateLsa>::const_iterator>(
@@ -127,8 +117,8 @@
 }
 
 void
-LsdbDatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
-                                              ndn::mgmt::StatusDatasetContext& context)
+DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                          ndn::mgmt::StatusDatasetContext& context)
 {
   auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator, std::list<NameLsa>::const_iterator>(
     m_lsdb.getNameLsdb().cbegin(), m_lsdb.getNameLsdb().cend());
@@ -150,24 +140,42 @@
 }
 
 void
-LsdbDatasetInterestHandler::publishAllStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
-                                             ndn::mgmt::StatusDatasetContext& context)
+DatasetInterestHandler::publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                                        ndn::mgmt::StatusDatasetContext& context)
 {
-  NLSR_LOG_DEBUG("Received interest:  " << interest);
-  tlv::LsdbStatus lsdbStatus;
-  for (const tlv::AdjacencyLsa& tlvLsa : getTlvLsas<tlv::AdjacencyLsa>(m_lsdb)) {
-    lsdbStatus.addAdjacencyLsa(tlvLsa);
+  NLSR_LOG_DEBUG("Received interest for routing table:  " << interest);
+  tlv::RoutingTable tlvRoutingTable;
+
+  for (const auto& rte : m_routingTableEntries) {
+    std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(rte);
+    tlvRoutingTable.setDestination(*tlvDes);
+
+    for (const auto& nh : rte.getNexthopList().getNextHops()) {
+      tlv::NextHop tlvNexthop;
+      tlvNexthop.setUri(nh.getConnectingFaceUri());
+      tlvNexthop.setCost(nh.getRouteCost());
+      tlvRoutingTable.addNexthops(tlvNexthop);
+    }
+
+    const ndn::Block& wire = tlvRoutingTable.wireEncode();
+    context.append(wire);
+  }
+  if (!m_dryRoutingTableEntries.empty()) {
+    for (const auto& dry_rte : m_dryRoutingTableEntries ) {
+        std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(dry_rte);
+        tlvRoutingTable.setDestination(*tlvDes);
+
+        for (const auto& nh : dry_rte.getNexthopList().getNextHops()) {
+          tlv::NextHop tlvNexthop;
+          tlvNexthop.setUri(nh.getConnectingFaceUri());
+          tlvNexthop.setCost(nh.getRouteCost());
+          tlvRoutingTable.addNexthops(tlvNexthop);
+        }
+        const ndn::Block& wire = tlvRoutingTable.wireEncode();
+        context.append(wire);
+      }
   }
 
-  for (const tlv::CoordinateLsa& tlvLsa : getTlvLsas<tlv::CoordinateLsa>(m_lsdb)) {
-    lsdbStatus.addCoordinateLsa(tlvLsa);
-  }
-
-  for (const tlv::NameLsa& tlvLsa : getTlvLsas<tlv::NameLsa>(m_lsdb)) {
-    lsdbStatus.addNameLsa(tlvLsa);
-  }
-  const ndn::Block& wire = lsdbStatus.wireEncode();
-  context.append(wire);
   context.end();
 }
 
@@ -250,5 +258,4 @@
 
 }
 
-
 } // namespace nlsr
diff --git a/src/publisher/lsdb-dataset-interest-handler.hpp b/src/publisher/dataset-interest-handler.hpp
similarity index 60%
rename from src/publisher/lsdb-dataset-interest-handler.hpp
rename to src/publisher/dataset-interest-handler.hpp
index e01a5da..00d8c1d 100644
--- a/src/publisher/lsdb-dataset-interest-handler.hpp
+++ b/src/publisher/dataset-interest-handler.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2018,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -19,31 +19,47 @@
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  **/
 
-#ifndef NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
-#define NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
+ /*! \file dataset-interest-handler.hpp
+
+  This file details a class that is used by NLSRC and other command-line
+  tools to examine the state of NLSR. This class doesn't only handle interest
+  from local host, but also handle interests from remote router.
+  This system is not designed to
+  be used by routers to publish data to each other.
+ */
+
+#ifndef NLSR_PUBLISHER_DATASET_INTEREST_HANDLER_HPP
+#define NLSR_PUBLISHER_DATASET_INTEREST_HANDLER_HPP
+
+#include "route/routing-table-entry.hpp"
+#include "route/routing-table.hpp"
+#include "route/nexthop-list.hpp"
+#include "lsdb.hpp"
+#include "logger.hpp"
 
 #include "tlv/adjacency-lsa.hpp"
 #include "tlv/coordinate-lsa.hpp"
 #include "tlv/name-lsa.hpp"
-#include "lsdb.hpp"
+#include "tlv/routing-table-status.hpp"
+#include "tlv/routing-table-entry.hpp"
 
 #include <ndn-cxx/mgmt/dispatcher.hpp>
 #include <ndn-cxx/face.hpp>
 #include <boost/noncopyable.hpp>
 
 namespace nlsr {
-
 namespace dataset {
-  const ndn::Name::Component ADJACENCY_COMPONENT = ndn::Name::Component{"adjacencies"};
-  const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component{"names"};
-  const ndn::Name::Component COORDINATE_COMPONENT = ndn::Name::Component{"coordinates"};
+const ndn::Name::Component ADJACENCY_COMPONENT = ndn::Name::Component{"adjacencies"};
+const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component{"names"};
+const ndn::Name::Component COORDINATE_COMPONENT = ndn::Name::Component{"coordinates"};
 } // namespace dataset
 
 /*!
-   \brief Class to publish all lsa dataset
+   \brief Class to publish all dataset
    \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
+   \sa https://redmine.named-data.net/projects/nlsr/wiki/Routing_Table_DataSet
  */
-class LsdbDatasetInterestHandler : boost::noncopyable
+class DatasetInterestHandler : boost::noncopyable
 {
 public:
   class Error : std::runtime_error
@@ -56,11 +72,11 @@
     }
   };
 
-  LsdbDatasetInterestHandler(Lsdb& lsdb,
-                             ndn::mgmt::Dispatcher& localHostDispatcher,
-                             ndn::mgmt::Dispatcher& routerNameDispatcher,
-                             ndn::Face& face,
-                             ndn::KeyChain& keyChain);
+  DatasetInterestHandler(const Lsdb& lsdb,
+                         const RoutingTable& rt,
+                         ndn::mgmt::Dispatcher& dispatcher,
+                         const ndn::Face& face,
+                         const ndn::KeyChain& keyChain);
 
   ndn::Name&
   getRouterNameCommandPrefix()
@@ -75,12 +91,17 @@
   }
 
 private:
-  /*! \brief Capture-point for Interests to verify Interests are
-   * valid, and then process them.
+  /*! \brief set dispatcher for localhost or remote router
    */
   void
   setDispatcher(ndn::mgmt::Dispatcher& dispatcher);
 
+  /*! \brief provide routing-table dataset
+  */
+  void
+  publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+                  ndn::mgmt::StatusDatasetContext& context);
+
   /*! \brief provide adjacent status dataset
    */
   void
@@ -99,18 +120,14 @@
   publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
                     ndn::mgmt::StatusDatasetContext& context);
 
-  /*! \brief provide ladb status dataset
-   */
-  void
-  publishAllStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
-                   ndn::mgmt::StatusDatasetContext& context);
-
 private:
   const Lsdb& m_lsdb;
   ndn::Name m_routerNamePrefix;
 
-  ndn::mgmt::Dispatcher& m_localhostDispatcher;
-  ndn::mgmt::Dispatcher& m_routerNameDispatcher;
+  ndn::mgmt::Dispatcher& m_dispatcher;
+
+  const std::list<RoutingTableEntry>& m_routingTableEntries;
+  const std::list<RoutingTableEntry>& m_dryRoutingTableEntries;
 };
 
 template<typename T> std::list<T>
@@ -127,4 +144,4 @@
 
 } // namespace nlsr
 
-#endif // NLSR_PUBLISHER_LSDB_DATASET_INTEREST_HANDLER_HPP
+#endif // NLSR_PUBLISHER_DATASET_INTEREST_HANDLER_HPP