validator: integrate validator-config

Validation of interest is done. Validation of data will be implemented in future commit.

Change-Id: I2c03172c6e0dfa9ec0c6cffa59999ecb30030243
refs #1479
diff --git a/src/common.hpp b/src/common.hpp
index 1f27bb3..317789c 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -27,7 +27,7 @@
 #include <ndn-cxx/selectors.hpp>
 #include <ndn-cxx/key-locator.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/command-interest-validator.hpp>
+#include <ndn-cxx/security/validator-config.hpp>
 #include <ndn-cxx/util/time.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
 
@@ -55,8 +55,8 @@
 using ndn::Data;
 using ndn::KeyLocator;
 using ndn::KeyChain;
-using ndn::CommandInterestValidator;
 using ndn::Scheduler;
+using ndn::ValidatorConfig;
 
 using ndn::bind;
 using ndn::shared_ptr;
diff --git a/src/handles/delete-handle.cpp b/src/handles/delete-handle.cpp
index d88d523..ad4a474 100644
--- a/src/handles/delete-handle.cpp
+++ b/src/handles/delete-handle.cpp
@@ -22,7 +22,7 @@
 namespace repo {
 
 DeleteHandle::DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
-                           Scheduler& scheduler, CommandInterestValidator& validator)
+                           Scheduler& scheduler, ValidatorConfig& validator)
   : BaseHandle(face, storageHandle, keyChain, scheduler)
   , m_validator(validator)
 {
@@ -31,9 +31,8 @@
 void
 DeleteHandle::onInterest(const Name& prefix, const Interest& interest)
 {
-  //std::cout << "call DeleteHandle" << std::endl;
   m_validator.validate(interest, bind(&DeleteHandle::onValidated, this, _1, prefix),
-                       bind(&DeleteHandle::onValidationFailed, this, _1, prefix));
+                       bind(&DeleteHandle::onValidationFailed, this, _1, _2));
 }
 
 void
@@ -97,9 +96,9 @@
 }
 
 void
-DeleteHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix)
+DeleteHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const string& reason)
 {
-  std::cout << "invalidated" << std::endl;
+  std::cerr << reason << std::endl;
   negativeReply(*interest, 401);
 }
 
diff --git a/src/handles/delete-handle.hpp b/src/handles/delete-handle.hpp
index 8ca1c56..5a3b33a 100644
--- a/src/handles/delete-handle.hpp
+++ b/src/handles/delete-handle.hpp
@@ -42,7 +42,7 @@
 
 public:
   DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
-               Scheduler& scheduler, CommandInterestValidator& validator);
+               Scheduler& scheduler, ValidatorConfig& validator);
 
   virtual void
   listen(const Name& prefix);
@@ -61,7 +61,7 @@
   onValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
 
   void
-  onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix);
+  onValidationFailed(const shared_ptr<const Interest>& interest, const string& reason);
 
   /**
   * @todo delete check has not been realized due to the while loop of segmented data deletion.
@@ -89,7 +89,7 @@
   processSegmentDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
 
 private:
-  CommandInterestValidator& m_validator;
+  ValidatorConfig& m_validator;
 
 };
 
diff --git a/src/handles/write-handle.cpp b/src/handles/write-handle.cpp
index 77c674b..91557f3 100644
--- a/src/handles/write-handle.cpp
+++ b/src/handles/write-handle.cpp
@@ -27,7 +27,7 @@
 static const ndn::time::milliseconds PROCESS_DELETE_TIME(10000);
 
 WriteHandle::WriteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
-                         Scheduler& scheduler, CommandInterestValidator& validator)
+                         Scheduler& scheduler, ValidatorConfig& validator)
   : BaseHandle(face, storageHandle, keyChain, scheduler)
   , m_validator(validator)
   , m_retryTime(RETRY_TIMEOUT)
@@ -48,7 +48,7 @@
 {
   m_validator.validate(interest,
                           bind(&WriteHandle::onValidated, this, _1, prefix),
-                          bind(&WriteHandle::onValidationFailed, this, _1));
+                          bind(&WriteHandle::onValidationFailed, this, _1, _2));
 }
 
 void
@@ -98,18 +98,15 @@
 }
 
 void
-WriteHandle::onValidationFailed(const shared_ptr<const Interest>& interest)
+WriteHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const string& reason)
 {
-  std::cout << "invalidated" << std::endl;
+  std::cerr << reason << std::endl;
   negativeReply(*interest, 401);
 }
 
 void
 WriteHandle::onData(const Interest& interest, ndn::Data& data, ProcessId processId)
 {
-  //std::cout << "onData" << std::endl;
-  //std::cout << "I: " << interest.toUri() << std::endl;
-  //std::cout << "D: " << data.getName().toUri() << std::endl;
   if (m_processes.count(processId) == 0) {
     return;
   }
@@ -128,10 +125,6 @@
 void
 WriteHandle::onSegmentData(const Interest& interest, Data& data, ProcessId processId)
 {
-  //std::cout << "I: " << interest.toUri() << std::endl;
-  //std::cout << "D: " << data.getName().toUri() << std::endl;
-  //retrieve the process from the responsemap
-
   if (m_processes.count(processId) == 0) {
     return;
   }
@@ -153,13 +146,9 @@
   }
 
   //insert data
-  //std::cout << "start to insert" << std::endl;
   if (getStorageHandle().insertData(data)) {
     response.setInsertNum(response.getInsertNum() + 1);
   }
-  //std::cout << "end of insert" << std::endl;
-
-  //it->second = response;
 
   onSegmentDataControl(processId, interest);
 }
@@ -167,14 +156,14 @@
 void
 WriteHandle::onTimeout(const ndn::Interest& interest, ProcessId processId)
 {
-  std::cout << "Timeout" << std::endl;
+  std::cerr << "Timeout" << std::endl;
   m_processes.erase(processId);
 }
 
 void
 WriteHandle::onSegmentTimeout(const Interest& interest, ProcessId processId)
 {
-  std::cout << "SegTimeout" << std::endl;
+  std::cerr << "SegTimeout" << std::endl;
 
   onSegmentTimeoutControl(processId, interest);
 }
@@ -224,7 +213,6 @@
     Name fetchName = name;
     fetchName.appendSegment(segment);
     Interest interest(fetchName);
-    //std::cout << "seg:" << j<<std::endl;
     getFace().expressInterest(interest,
                               bind(&WriteHandle::onSegmentData, this, _1, _2, processId),
                               bind(&WriteHandle::onSegmentTimeout, this, _1, processId));
@@ -241,8 +229,6 @@
 void
 WriteHandle::onSegmentDataControl(ProcessId processId, const Interest& interest)
 {
-  //std::cout << "onSegmentDataControl: " << processId << std::endl;
-
   if (m_processes.count(processId) == 0) {
     return;
   }
@@ -263,7 +249,7 @@
     ndn::time::steady_clock::TimePoint now = ndn::time::steady_clock::now();
 
     if (now > noEndTime) {
-      std::cout << "noEndtimeout: " << processId << std::endl;
+      std::cerr << "noEndtimeout: " << processId << std::endl;
       //m_processes.erase(processId);
       //StatusCode should be refreshed as 405
       response.setStatusCode(405);
@@ -325,7 +311,6 @@
                             bind(&WriteHandle::onSegmentTimeout, this, _1, processId));
   //When an interest is expressed, processCredit--
   processCredit--;
-  //std::cout << "sent seg: " << sendingSegment << std::endl;
   if (retryCounts.count(sendingSegment) == 0) {
     //not found
     retryCounts[sendingSegment] = 0;
@@ -355,7 +340,7 @@
 
   SegmentNo timeoutSegment = interest.getName().get(-1).toSegment();
 
-  std::cout << "timeoutSegment: " << timeoutSegment << std::endl;
+  std::cerr << "timeoutSegment: " << timeoutSegment << std::endl;
 
   BOOST_ASSERT(retryCounts.count(timeoutSegment) != 0);
 
@@ -363,7 +348,7 @@
   int& retryTime = retryCounts[timeoutSegment];
   if (retryTime >= m_retryTime) {
     //fail this process
-    std::cout << "Retry timeout: " << processId << std::endl;
+    std::cerr << "Retry timeout: " << processId << std::endl;
     m_processes.erase(processId);
     return;
   }
@@ -406,7 +391,7 @@
   //check whether this process exists
   ProcessId processId = parameter.getProcessId();
   if (m_processes.count(processId) == 0) {
-    std::cout << "no such processId: " << processId << std::endl;
+    std::cerr << "no such processId: " << processId << std::endl;
     negativeReply(*interest, 404);
     return;
   }
@@ -484,8 +469,6 @@
 
     SegmentNo startBlockId = parameter.getStartBlockId();
     SegmentNo endBlockId = parameter.getEndBlockId();
-    //std::cout << "startBlockId: " << startBlockId << std::endl;
-    //std::cout << "endBlockId: " << endBlockId << std::endl;
     if (startBlockId > endBlockId) {
       negativeReply(interest, 403);
       return;
@@ -493,7 +476,6 @@
 
     ProcessId processId = generateProcessId();
     ProcessInfo& process = m_processes[processId];
-    //std::cout << "processId: " << processId << std::endl;
     RepoCommandResponse& response = process.response;
     response.setStatusCode(100);
     response.setProcessId(processId);
@@ -512,7 +494,6 @@
     //no EndBlockId, so fetch FinalBlockId in data, if timeout, stop
     ProcessId processId = generateProcessId();
     ProcessInfo& process = m_processes[processId];
-    //std::cout << "processId: " << processId << std::endl;
     RepoCommandResponse& response = process.response;
     response.setStatusCode(100);
     response.setProcessId(processId);
diff --git a/src/handles/write-handle.hpp b/src/handles/write-handle.hpp
index 59fefb6..1fe147a 100644
--- a/src/handles/write-handle.hpp
+++ b/src/handles/write-handle.hpp
@@ -68,7 +68,7 @@
 
 public:
   WriteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
-              Scheduler& scheduler, CommandInterestValidator& validator);
+              Scheduler& scheduler, ValidatorConfig& validator);
 
   virtual void
   listen(const Name& prefix);
@@ -110,7 +110,7 @@
   onValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
 
   void
-  onValidationFailed(const shared_ptr<const Interest>& interest);
+  onValidationFailed(const shared_ptr<const Interest>& interest, const string& reason);
 
   void
   onRegisterSuccess(const Name& prefix);
@@ -214,7 +214,7 @@
 
 private:
 
-  CommandInterestValidator& m_validator;
+  ValidatorConfig& m_validator;
 
   map<ProcessId, ProcessInfo> m_processes;
 
diff --git a/src/main.cpp b/src/main.cpp
index e69c32d..999b7b8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -82,6 +82,8 @@
     signalSet.async_wait(bind(&terminate, boost::ref(ioService), _1, _2,
                               boost::ref(signalSet)));
 
+    repoInstance.enableValidation();
+
     repoInstance.enableListening();
 
     ioService.run();
diff --git a/src/repo.cpp b/src/repo.cpp
index 2c6f3b0..d868508 100644
--- a/src/repo.cpp
+++ b/src/repo.cpp
@@ -44,9 +44,9 @@
   ptree repoConf = propertyTree.get_child("repo");
 
   RepoConfig repoConfig;
+  repoConfig.repoConfigPath = configPath;
 
   ptree dataConf = repoConf.get_child("data");
-
   for (ptree::const_iterator it = dataConf.begin();
        it != dataConf.end();
        ++it)
@@ -112,17 +112,13 @@
   , m_scheduler(ioService)
   , m_face(ioService)
   , m_storageHandle(openStorage(config))
+  , m_validator(m_face)
   , m_readHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler)
   , m_writeHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
   , m_deleteHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
   , m_tcpBulkInsertHandle(ioService, *m_storageHandle)
 
 {
-  //Trust model not implemented, this is just an empty validator
-  //@todo add a function to parse RepoConfig.validatorNode and define the trust model
-  m_validator.addInterestRule("^<>",
-                              *m_keyChain.
-                              getCertificate(m_keyChain.getDefaultCertificateName()));
 }
 
 shared_ptr<StorageHandle>
@@ -161,4 +157,10 @@
     }
 }
 
+void
+Repo::enableValidation()
+{
+  m_validator.load(m_config.validatorNode, m_config.repoConfigPath);
+}
+
 } // namespace repo
diff --git a/src/repo.hpp b/src/repo.hpp
index a92eb7d..b56b5dc 100644
--- a/src/repo.hpp
+++ b/src/repo.hpp
@@ -28,8 +28,7 @@
 #include "handles/delete-handle.hpp"
 #include "handles/tcp-bulk-insert-handle.hpp"
 
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/command-interest-validator.hpp>
+#include "common.hpp"
 
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/info_parser.hpp>
@@ -42,13 +41,12 @@
 
 struct RepoConfig
 {
+  string repoConfigPath;
   //StorageMethod storageMethod; This will be implemtented if there is other method.
   std::string dbPath;
   vector<ndn::Name> dataPrefixes;
   vector<ndn::Name> repoPrefixes;
   vector<pair<string, string> > tcpBulkInsertEndpoints;
-
-  //@todo validator should be configured in config file
   boost::property_tree::ptree validatorNode;
 };
 
@@ -75,6 +73,9 @@
   void
   enableListening();
 
+  void
+  enableValidation();
+
 private:
   static shared_ptr<StorageHandle>
   openStorage(const RepoConfig& config);
@@ -85,7 +86,7 @@
   ndn::Face m_face;
   shared_ptr<StorageHandle> m_storageHandle;
   KeyChain m_keyChain;
-  CommandInterestValidator m_validator;
+  ValidatorConfig m_validator;
   ReadHandle m_readHandle;
   WriteHandle m_writeHandle;
   DeleteHandle m_deleteHandle;
diff --git a/tests/integrated/insert-delete-validator-config.conf b/tests/integrated/insert-delete-validator-config.conf
new file mode 100644
index 0000000..e5a44f8
--- /dev/null
+++ b/tests/integrated/insert-delete-validator-config.conf
@@ -0,0 +1,26 @@
+; This test rule is for test suite TestBasicCommandInsertDelete.
+; Signed interests are generated by default certificate.
+; In this test rule, the type of checker is fixed signer and signer type is file.
+; So user who wants to run this test could use security tool to dump the defualt
+; certificate into a file named "insert-delete-test.cert"
+rule
+{
+  id "Test Rule For Signed Interest"
+  for interest
+  filter
+  {
+    type name
+    name /
+    relation is-prefix-of
+  }
+  checker
+  {
+    type fixed-signer
+    sig-type rsa-sha256
+    signer
+    {
+      type file
+      file-name "insert-delete-test.cert"
+    }
+  }
+}
\ No newline at end of file
diff --git a/tests/integrated/test-basic-command-insert-delete.cpp b/tests/integrated/test-basic-command-insert-delete.cpp
index 189ee27..eed4764 100644
--- a/tests/integrated/test-basic-command-insert-delete.cpp
+++ b/tests/integrated/test-basic-command-insert-delete.cpp
@@ -21,13 +21,16 @@
 #include "handles/delete-handle.hpp"
 #include "storage/storage-handle.hpp"
 #include "storage/sqlite-handle.hpp"
+#include "common.hpp"
 
 #include "../sqlite-fixture.hpp"
 #include "../dataset-fixtures.hpp"
 
-#include <ndn-cxx/util/command-interest-generator.hpp>
+#include <ndn-cxx/util/random.hpp>
+#include <ndn-cxx/util/io.hpp>
 
 #include <boost/test/unit_test.hpp>
+#include <fstream>
 
 namespace repo {
 namespace tests {
@@ -48,13 +51,12 @@
 public:
   Fixture()
     : scheduler(repoFace.getIoService())
+    , validator(repoFace)
     , writeHandle(repoFace, *handle, keyChain, scheduler, validator)
     , deleteHandle(repoFace, *handle, keyChain, scheduler, validator)
     , insertFace(repoFace.getIoService())
     , deleteFace(repoFace.getIoService())
   {
-    validator.addInterestRule("^<>",
-                              *keyChain.getCertificate(keyChain.getDefaultCertificateName()));
     writeHandle.listen(Name("/repo/command"));
     deleteHandle.listen(Name("/repo/command"));
   }
@@ -65,6 +67,9 @@
   }
 
   void
+  generateDefaultCertificateFile();
+
+  void
   scheduleInsertEvent();
 
   void
@@ -102,17 +107,16 @@
   sendDeleteInterest(const Interest& deleteInterest);
 
   void
-  checkInsertOK(const Interest& interest);
+  checkInsertOk(const Interest& interest);
 
   void
-  checkDeleteOK(const Interest& interest);
+  checkDeleteOk(const Interest& interest);
 
 public:
   Face repoFace;
   Scheduler scheduler;
-  CommandInterestValidator validator;
+  ValidatorConfig validator;
   KeyChain keyChain;
-  ndn::CommandInterestGenerator generator;
   WriteHandle writeHandle;
   DeleteHandle deleteHandle;
   Face insertFace;
@@ -120,6 +124,22 @@
   std::map<Name, EventId> insertEvents;
 };
 
+template<class T>  void
+Fixture<T>::generateDefaultCertificateFile()
+{
+  Name defaultIdentity = keyChain.getDefaultIdentity();
+  Name defaultKeyname = keyChain.getDefaultKeyNameForIdentity(defaultIdentity);
+  Name defaultCertficateName = keyChain.getDefaultCertificateNameForKey(defaultKeyname);
+  shared_ptr<ndn::IdentityCertificate> defaultCertficate =
+    keyChain.getCertificate(defaultCertficateName);
+  //test-integrated should run in root directory of repo-ng.
+  //certificate file should be removed after tests for security issue.
+  std::fstream certificateFile("tests/integrated/insert-delete-test.cert",
+                               std::ios::out | std::ios::binary | std::ios::trunc);
+  ndn::io::save(*defaultCertficate, certificateFile);
+  certificateFile.close();
+}
+
 template<class T> void
 Fixture<T>::onInsertInterest(const Interest& interest)
 {
@@ -134,9 +154,9 @@
     scheduler.cancelEvent(event->second);
     insertEvents.erase(event);
   }
-  // schedule an event 50ms later to check whether insert is OK
+  // schedule an event 50ms later to check whether insert is Ok
   scheduler.scheduleEvent(milliseconds(50),
-                          bind(&Fixture<T>::checkInsertOK, this, interest));
+                          bind(&Fixture<T>::checkInsertOk, this, interest));
 
 }
 
@@ -176,9 +196,9 @@
   int statusCode = response.getStatusCode();
   BOOST_CHECK_EQUAL(statusCode, 200);
 
-  //schedlute an event to check whether delete is OK.
+  //schedlute an event to check whether delete is Ok.
   scheduler.scheduleEvent(milliseconds(100),
-                          bind(&Fixture<T>::checkDeleteOK, this, interest));
+                          bind(&Fixture<T>::checkDeleteOk, this, interest));
 }
 
 template<class T> void
@@ -210,7 +230,7 @@
 }
 
 template<class T> void
-Fixture<T>::checkInsertOK(const Interest& interest)
+Fixture<T>::checkInsertOk(const Interest& interest)
 {
   Data data;
   BOOST_TEST_MESSAGE(interest);
@@ -220,7 +240,7 @@
 }
 
 template<class T> void
-Fixture<T>::checkDeleteOK(const Interest& interest)
+Fixture<T>::checkDeleteOk(const Interest& interest)
 {
   Data data;
   BOOST_CHECK_EQUAL(handle->readData(interest, data), false);
@@ -240,7 +260,7 @@
 
     insertCommandName.append(insertParameter.wireEncode());
     Interest insertInterest(insertCommandName);
-    generator.generateWithIdentity(insertInterest, keyChain.getDefaultIdentity());
+    keyChain.signByIdentity(insertInterest, keyChain.getDefaultIdentity());
     //schedule a job to express insertInterest every 50ms
     scheduler.scheduleEvent(milliseconds(timeCount * 50 + 1000),
                             bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
@@ -274,7 +294,7 @@
     deleteParameter.setName((*i)->getName());
     deleteCommandName.append(deleteParameter.wireEncode());
     Interest deleteInterest(deleteCommandName);
-    generator.generateWithIdentity(deleteInterest, keyChain.getDefaultIdentity());
+    keyChain.signByIdentity(deleteInterest, keyChain.getDefaultIdentity());
     scheduler.scheduleEvent(milliseconds(4000 + timeCount * 50),
                             bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
     timeCount++;
@@ -283,6 +303,9 @@
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, DatasetFixtures, Fixture<T>)
 {
+  this->generateDefaultCertificateFile();
+  this->validator.load("tests/integrated/insert-delete-validator-config.conf");
+
   // schedule events
   this->scheduler.scheduleEvent(seconds(0),
                                 bind(&Fixture<T>::scheduleInsertEvent, this));