ndn-handle: Implementatation of delete

Delete without EndBlockId and delete check are not supported yet.

Change-Id: Ib971e9ed8db412dae86d07f87e168dea11f51b0b
diff --git a/ndn-handle/delete-handle.cpp b/ndn-handle/delete-handle.cpp
new file mode 100644
index 0000000..8e1130c
--- /dev/null
+++ b/ndn-handle/delete-handle.cpp
@@ -0,0 +1,184 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "delete-handle.hpp"
+
+namespace repo {
+
+DeleteHandle::DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+                           Scheduler& scheduler, CommandInterestValidator& validator)
+  : BaseHandle(face, storageHandle, keyChain, scheduler)
+  , m_validator(validator)
+{
+}
+
+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));
+}
+
+
+void
+DeleteHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Delete prefix registration failed");
+}
+
+
+void
+DeleteHandle::onCheckInterest(const Name& prefix, const Interest& interest)
+{
+  BOOST_ASSERT(false); // Deletion progress check, not implemented
+}
+
+
+void
+DeleteHandle::onCheckRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Delete check prefix registration failed");
+}
+
+
+void
+DeleteHandle::onValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  if (parameter.hasSelectors()) {
+
+    if (parameter.hasStartBlockId() || parameter.hasEndBlockId()) {
+      negativeReply(*interest, 402);
+      return;
+    }
+
+    //choose data with selector and delete it
+    processSelectorDeleteCommand(*interest, parameter);
+    return;
+  }
+
+  if (!parameter.hasStartBlockId() && !parameter.hasEndBlockId()) {
+    processSingleDeleteCommand(*interest, parameter);
+    return;
+  }
+
+  processSegmentDeleteCommand(*interest, parameter);
+}
+
+void
+DeleteHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  std::cout << "invalidated" << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+DeleteHandle::listen(const Name& prefix)
+{
+  getFace().setInterestFilter(prefix,
+                              bind(&DeleteHandle::onInterest, this, _1, _2),
+                              bind(&DeleteHandle::onRegisterFailed, this, _1, _2));
+}
+
+void
+DeleteHandle::positiveReply(const Interest& interest, const RepoCommandParameter& parameter,
+                            uint64_t statusCode, uint64_t nDeletedDatas)
+{
+  RepoCommandResponse response;
+  if (parameter.hasProcessId()) {
+    response.setProcessId(parameter.getProcessId());
+    response.setStatusCode(statusCode);
+    response.setDeleteNum(nDeletedDatas);
+  }
+  else {
+    response.setStatusCode(403);
+  }
+  reply(interest, response);
+}
+
+void
+DeleteHandle::negativeReply(const Interest& interest, uint64_t statusCode)
+{
+  RepoCommandResponse response;
+  response.setStatusCode(statusCode);
+  reply(interest, response);
+}
+
+void
+DeleteHandle::processSingleDeleteCommand(const Interest& interest,
+                                         RepoCommandParameter& parameter)
+{
+  uint64_t nDeletedDatas = 0;
+  if (getStorageHandle().deleteData(parameter.getName())) {
+    nDeletedDatas++;
+  }
+  positiveReply(interest, parameter, 200, nDeletedDatas);
+}
+
+void
+DeleteHandle::processSelectorDeleteCommand(const Interest& interest,
+                                           RepoCommandParameter& parameter)
+{
+  uint64_t nDeletedDatas = 0;
+  Name name = parameter.getName();
+  Selectors selectors = parameter.getSelectors();
+  vector<Name> names;
+  getStorageHandle().readNameAny(name, selectors, names);
+
+  for (vector<Name>::iterator it = names.begin(); it != names.end(); ++it) {
+    if (getStorageHandle().deleteData(*it)) {
+      nDeletedDatas++;
+    }
+  }
+
+  //All data has been deleted, return 200
+  positiveReply(interest, parameter, 200, nDeletedDatas);
+}
+
+void
+DeleteHandle::processSegmentDeleteCommand(const Interest& interest,
+                                          RepoCommandParameter& parameter)
+{
+  if (!parameter.hasStartBlockId())
+    parameter.setStartBlockId(0);
+
+  if (parameter.hasEndBlockId()) {
+    SegmentNo startBlockId = parameter.getStartBlockId();
+    SegmentNo endBlockId = parameter.getEndBlockId();
+
+    if (startBlockId > endBlockId) {
+      negativeReply(interest, 403);
+      return;
+    }
+
+    Name prefix = parameter.getName();
+    uint64_t nDeletedDatas = 0;
+    for (SegmentNo i = startBlockId; i <= endBlockId; i++) {
+      Name name = prefix;
+      name.appendSegment(i);
+      if (getStorageHandle().deleteData(name)) {
+        nDeletedDatas++;
+      }
+    }
+    //All the data deleted, return 200
+    positiveReply(interest, parameter, 200, nDeletedDatas);
+  }
+  else {
+    BOOST_ASSERT(false); // segmented deletion without EndBlockId, not implemented
+  }
+}
+
+} //namespace repo
diff --git a/ndn-handle/delete-handle.hpp b/ndn-handle/delete-handle.hpp
new file mode 100644
index 0000000..e69938b
--- /dev/null
+++ b/ndn-handle/delete-handle.hpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef REPO_NDN_HANDLE_DELETE_HANDLE_HPP
+#define REPO_NDN_HANDLE_DELETE_HANDLE_HPP
+
+#include "ndn-handle-common.hpp"
+#include "base-handle.hpp"
+
+namespace repo {
+
+using std::vector;
+
+class DeleteHandle : public BaseHandle
+{
+
+public:
+  class Error : public BaseHandle::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BaseHandle::Error(what)
+    {
+    }
+  };
+
+public:
+  DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+               Scheduler& scheduler, CommandInterestValidator& validator);
+
+  virtual void
+  listen(const Name& prefix);
+
+private:
+  void
+  onInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason);
+
+  void
+  onValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  void
+  onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  /**
+  * @todo delete check has not been realized due to the while loop of segmented data deletion.
+  */
+  void
+  onCheckInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onCheckRegisterFailed(const Name& prefix, const std::string& reason);
+
+  void
+  positiveReply(const Interest& interest, const RepoCommandParameter& parameter,
+                uint64_t statusCode, uint64_t nDeletedDatas);
+
+  void
+  negativeReply(const Interest& interest, uint64_t statusCode);
+
+  void
+  processSingleDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+  void
+  processSelectorDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+  void
+  processSegmentDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+private:
+  CommandInterestValidator& m_validator;
+
+};
+
+} //namespace repo
+
+#endif // REPO_NDN_HANDLE_DELETE_HANDLE_HPP
diff --git a/ndn-handle/write-handle.cpp b/ndn-handle/write-handle.cpp
index dac5ca8..68fc2a6 100644
--- a/ndn-handle/write-handle.cpp
+++ b/ndn-handle/write-handle.cpp
@@ -328,9 +328,9 @@
     return;
   }
   ProcessInfo& process = m_processes[processId];
-  RepoCommandResponse& response = process.response;
-  SegmentNo& nextSegment = process.nextSegment;
-  queue<SegmentNo>& nextSegmentQueue = process.nextSegmentQueue;
+  // RepoCommandResponse& response = process.response;
+  // SegmentNo& nextSegment = process.nextSegment;
+  // queue<SegmentNo>& nextSegmentQueue = process.nextSegmentQueue;
   map<SegmentNo, int>& retryCounts = process.retryCounts;
 
   SegmentNo timeoutSegment = interest.getName().get(-1).toSegment();
diff --git a/server/server.cpp b/server/server.cpp
index 7e43180..4ea011a 100644
--- a/server/server.cpp
+++ b/server/server.cpp
@@ -13,6 +13,7 @@
 #include "../storage/sqlite/sqlite-handle.hpp"
 #include "../ndn-handle/read-handle.hpp"
 #include "../ndn-handle/write-handle.hpp"
+#include "../ndn-handle/delete-handle.hpp"
 
 using namespace repo;
 
@@ -68,7 +69,8 @@
   readHandle.listen(dataPrefix);
   WriteHandle writeHandle(face, sqliteHandle, keyChain, scheduler, validator);
   writeHandle.listen(repoPrefix);
-
+  DeleteHandle deleteHandle(face, sqliteHandle, keyChain, scheduler, validator);
+  deleteHandle.listen(repoPrefix);
   face.processEvents();
   return 0;
 }