fix RDR use in ca and requester

Change-Id: Iff81b7a061670941276043aac3334695c645ee4e
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 3560568..43becc5 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -77,8 +77,14 @@
   auto prefixId = m_face.registerPrefix(
       prefix,
       [&](const Name& name) {
+        // register INFO RDR metadata prefix
+        name::Component metaDataComp(32, reinterpret_cast<const uint8_t*>("metadata"), std::strlen("metadata"));
+        auto filterId = m_face.setInterestFilter(Name(name).append("INFO").append(metaDataComp),
+                                                 bind(&CaModule::onCaProfileDiscovery, this, _2));
+        m_interestFilterHandles.push_back(filterId);
+
         // register PROBE prefix
-        auto filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
+        filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
                                                  bind(&CaModule::onProbe, this, _2));
         m_interestFilterHandles.push_back(filterId);
 
@@ -108,32 +114,12 @@
   m_config.m_statusUpdateCallback = onUpdateCallback;
 }
 
-shared_ptr<Data>
-CaModule::generateCaProfileMetaData()
+Data
+CaModule::getCaProfileData()
 {
-  // @TODO
-  // make metadata a class member variable m_infoMetadata
-  // check whether the m_infoMetadata has the latest versioned name, if not, then generate a new one
-  // otherwise, directly reply m_infoMetadata.makeData
-
-  auto infoPacket = generateCaProfileData();
-  MetadataObject metadata;
-  metadata.setVersionedName(infoPacket->getName().getPrefix(-1));
-  Name discoveryInterestName(infoPacket->getName().getPrefix(-2));
-  name::Component metadataComponent(32, reinterpret_cast<const uint8_t*>("metadata"), std::strlen("metadata"));
-  discoveryInterestName.append(metadataComponent);
-  auto metadataData = metadata.makeData(discoveryInterestName, m_keyChain, signingByIdentity(m_config.m_caItem.m_caPrefix));
-  return make_shared<Data>(metadataData);
-}
-
-shared_ptr<Data>
-CaModule::generateCaProfileData()
-{
-  // @TODO
-  // make CaInfo Data packet a class member variable m_infoData
-  // check whether the m_infoData is still valid, if not, then generate a new one
-  // otherwise, directly reply m_infoData
-
+  if (m_profileData) {
+    return *m_profileData;
+  }
   const auto& pib = m_keyChain.getPib();
   const auto& identity = pib.getIdentity(m_config.m_caItem.m_caPrefix);
   const auto& cert = identity.getDefaultKey().getDefaultCertificate();
@@ -141,11 +127,26 @@
 
   Name infoPacketName(m_config.m_caItem.m_caPrefix);
   infoPacketName.append("CA").append("INFO").appendVersion().appendSegment(0);
-  Data infoData(infoPacketName);
-  infoData.setContent(contentTLV);
-  infoData.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
-  m_keyChain.sign(infoData, signingByIdentity(m_config.m_caItem.m_caPrefix));
-  return make_shared<Data>(infoData);
+  m_profileData = std::make_unique<Data>(infoPacketName);
+  m_profileData->setContent(contentTLV);
+  m_profileData->setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
+  m_keyChain.sign(*m_profileData, signingByIdentity(m_config.m_caItem.m_caPrefix));
+  return *m_profileData;
+}
+
+void
+CaModule::onCaProfileDiscovery(const Interest& request)
+{
+  _LOG_TRACE("Received CA Profile MetaData discovery Interest");
+  if (m_profileData == nullptr) {
+    m_profileData = std::make_unique<Data>(getCaProfileData());
+  }
+  MetadataObject metadata;
+  metadata.setVersionedName(m_profileData->getName().getPrefix(-1));
+  Name discoveryInterestName(m_profileData->getName().getPrefix(-2));
+  name::Component metadataComponent(32, reinterpret_cast<const uint8_t*>("metadata"), std::strlen("metadata"));
+  discoveryInterestName.append(metadataComponent);
+  m_face.put(metadata.makeData(discoveryInterestName, m_keyChain, signingByIdentity(m_config.m_caItem.m_caPrefix)));
 }
 
 void
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 4d6bebe..04d594f 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -51,12 +51,12 @@
   void
   setStatusUpdateCallback(const StatusUpdateCallback& onUpdateCallback);
 
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  shared_ptr<Data>
-  generateCaProfileMetaData();
+  Data
+  getCaProfileData();
 
-  shared_ptr<Data>
-  generateCaProfileData();
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  onCaProfileDiscovery(const Interest& request);
 
   void
   onProbe(const Interest& request);
@@ -88,6 +88,7 @@
   unique_ptr<CaStorage> m_storage;
   security::v2::KeyChain& m_keyChain;
   uint8_t m_requestIdGenKey[32];
+  std::unique_ptr<Data> m_profileData;
 
   std::list<RegisteredPrefixHandle> m_registeredPrefixHandles;
   std::list<InterestFilterHandle> m_interestFilterHandles;
diff --git a/tests/unit-tests/bench.t.cpp b/tests/unit-tests/bench.t.cpp
index c768035..13adf8c 100644
--- a/tests/unit-tests/bench.t.cpp
+++ b/tests/unit-tests/bench.t.cpp
@@ -38,24 +38,20 @@
 
   util::DummyClientFace face(io, m_keyChain, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
-  auto metaData = ca.generateCaProfileMetaData();
-  auto profileData = ca.generateCaProfileData();
+  auto profileData = ca.getCaProfileData();
   advanceClocks(time::milliseconds(20), 60);
 
   Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
   std::cout << "CA Config discovery Interest Size: " << interest.wireEncode().size() << std::endl;
   shared_ptr<Interest> infoInterest = nullptr;
 
-  face.setInterestFilter(InterestFilter("/ndn/CA/INFO"),
-                         [&](const auto&, const Interest& interest) {
-                           if (interest.matchesData(*metaData)) {
-                             face.put(*metaData);
-                           }
-                           else {
-                             BOOST_CHECK(interest.matchesData(*profileData));
-                             face.put(*profileData);
-                           }
-                         }, nullptr, nullptr);
+  face.setInterestFilter(
+      InterestFilter("/ndn/CA/INFO"),
+      [&](const auto&, const Interest& interest) {
+        BOOST_CHECK(interest.matchesData(profileData));
+        face.put(profileData);
+      },
+      nullptr, nullptr);
   advanceClocks(time::milliseconds(20), 60);
 
   int count = 0;
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 9484196..a7b9875 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -40,7 +40,7 @@
 
   advanceClocks(time::milliseconds(20), 60);
   BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 1); // removed local discovery registration
-  BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 4);  // onProbe, onNew, onChallenge, onRevoke
+  BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5);  // infoMeta, onProbe, onNew, onChallenge, onRevoke
 }
 
 BOOST_AUTO_TEST_CASE(HandleProfileFetching)
@@ -51,23 +51,18 @@
 
   util::DummyClientFace face(io, m_keyChain, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
-  auto metaData = ca.generateCaProfileMetaData();
-  auto profileData = ca.generateCaProfileData();
+  auto profileData = ca.getCaProfileData();
   advanceClocks(time::milliseconds(20), 60);
 
   Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
   shared_ptr<Interest> infoInterest = nullptr;
 
-  face.setInterestFilter(InterestFilter("/ndn/CA/INFO"),
-                         [&](const auto&, const Interest& interest) {
-                           if (interest.matchesData(*metaData)) {
-                             face.put(*metaData);
-                           }
-                           else {
-                             BOOST_CHECK(interest.matchesData(*profileData));
-                             face.put(*profileData);
-                           }
-                         }, nullptr, nullptr);
+  face.setInterestFilter(
+      InterestFilter("/ndn/CA/INFO"),
+      [&](const auto&, const Interest& interest) {
+        BOOST_CHECK(interest.matchesData(profileData));
+        face.put(profileData);
+      }, nullptr, nullptr);
   advanceClocks(time::milliseconds(20), 60);
 
   int count = 0;
diff --git a/tools/ndncert-ca-server.cpp b/tools/ndncert-ca-server.cpp
index a331e7e..281e7fe 100644
--- a/tools/ndncert-ca-server.cpp
+++ b/tools/ndncert-ca-server.cpp
@@ -114,12 +114,10 @@
 
   CaModule ca(face, keyChain, configFilePath);
   std::map<Name, Data> cachedCertificates;
-  auto profileMetaData = ca.generateCaProfileMetaData();
-  auto profileData = ca.generateCaProfileData();
+  auto profileData = ca.getCaProfileData();
 
   if (wantRepoOut) {
-    writeDataToRepo(*profileMetaData);
-    writeDataToRepo(*profileData);
+    writeDataToRepo(profileData);
     ca.setStatusUpdateCallback([&](const CaState& request) {
       if (request.m_status == Status::SUCCESS) {
         writeDataToRepo(request.m_cert);
@@ -132,8 +130,7 @@
         cachedCertificates[request.m_cert.getName()] = request.m_cert;
       }
     });
-    cachedCertificates[profileMetaData->getName()] = *profileMetaData;
-    cachedCertificates[profileData->getName()] = *profileData;
+    cachedCertificates[profileData.getName()] = profileData;
     face.setInterestFilter(
         InterestFilter(ca.getCaConf().m_caItem.m_caPrefix),
         [&](const InterestFilter&, const Interest& interest) {
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index b2f4d4e..1324bba 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -276,9 +276,10 @@
   else {
     //redirects
     auto redirectedCaFullName = redirects[index - names.size()];
-    std::cerr << "You selected redirects with certificate: " << redirectedCaFullName.getPrefix(-1).toUri() << std::endl;
+    auto redirectedCaName = security::v2::extractIdentityFromCertName(redirectedCaFullName.getPrefix(-1));
+    std::cerr << "You selected to be redirected to CA: " << redirectedCaName.toUri() << std::endl;
     face.expressInterest(
-        *Requester::genCaProfileDiscoveryInterest(redirectedCaFullName.getPrefix(-1)),
+        *Requester::genCaProfileDiscoveryInterest(redirectedCaName),
         [&](const Interest&, const Data& data) {
           auto fetchingInterest = Requester::genCaProfileInterestFromDiscoveryResponse(data);
           face.expressInterest(*fetchingInterest,