Almost reverting changes in naming convention: moving "user" name to
front, but still keeping application name.  As part of an additional
change, shared folder name in actions is moved just after "action"
keyword

Making AddRemoteAction call exception-free

Change-Id: Ifd0a0c6256940eaf6df8081722ae9d7ed40b12e5
diff --git a/src/action-log.cc b/src/action-log.cc
index 19c5c9d..6be38ee 100644
--- a/src/action-log.cc
+++ b/src/action-log.cc
@@ -239,8 +239,8 @@
   string item_msg;
   item->SerializeToString (&item_msg);
 
-  // action name: /<appname>/<shared-folder>/action/<device_name>/<action-seq>
-  Name actionName = Name ("/")(m_appName)(m_sharedFolderName)("action")(m_syncLog->GetLocalName ())(seq_no);
+  // action name: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
+  Name actionName = Name ("/")(m_syncLog->GetLocalName ())(m_appName)("action")(m_sharedFolderName)(seq_no);
   _LOG_DEBUG ("ActionName: " << actionName);
 
   Bytes actionData = m_ccnx->createContentObject (actionName, item_msg.c_str (), item_msg.size ());
@@ -341,8 +341,8 @@
   string item_msg;
   item->SerializeToString (&item_msg);
 
-  // action name: /<appname>/<shared-folder>/action/<device_name>/<action-seq>
-  Name actionName = Name ("/")(m_appName)(m_sharedFolderName)("action")(m_syncLog->GetLocalName ())(seq_no);
+  // action name: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
+  Name actionName = Name ("/")(m_syncLog->GetLocalName ())(m_appName)("action")(m_sharedFolderName)(seq_no);
   _LOG_DEBUG ("ActionName: " << actionName);
 
   Bytes actionData = m_ccnx->createContentObject (actionName, item_msg.c_str (), item_msg.size ());
@@ -450,13 +450,15 @@
 {
   if (!actionPco)
     {
-      BOOST_THROW_EXCEPTION (Error::ActionLog () << errmsg_info_str ("actionPco is not valid"));
+      _LOG_ERROR ("actionPco is not valid");
+      return ActionItemPtr ();
     }
   ActionItemPtr action = deserializeMsg<ActionItem> (actionPco->content ());
 
   if (!action)
     {
-      BOOST_THROW_EXCEPTION (Error::ActionLog () << errmsg_info_str ("action cannot be decoded"));
+      _LOG_ERROR ("action cannot be decoded");
+      return ActionItemPtr ();
     }
 
   _LOG_DEBUG ("AddRemoteAction: [" << deviceName << "] seqno: " << seqno);
@@ -520,23 +522,33 @@
 ActionLog::AddRemoteAction (Ccnx::PcoPtr actionPco)
 {
   Name name = actionPco->name ();
-  // action name: /<appname>/<shared-folder>/action/<device_name>/<action-seq>
+  // action name: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
 
-  uint64_t seqno = name.getCompFromBackAsInt (0);
-  string sharedFolder = name.getCompAsString (1);
+  uint64_t seqno      = name.getCompFromBackAsInt (0);
+  string sharedFolder = name.getCompFromBackAsString (1);
 
   if (sharedFolder != m_sharedFolderName)
     {
-      BOOST_THROW_EXCEPTION (Error::ActionLog () << errmsg_info_str ("Action doesn't belong to this shared folder"));
+      _LOG_ERROR ("Action doesn't belong to this shared folder");
+      return ActionItemPtr ();
     }
 
-  string action = name.getCompAsString (2);
+  string action = name.getCompFromBackAsString (2);
 
   if (action != "action")
     {
-      BOOST_THROW_EXCEPTION (Error::ActionLog () << errmsg_info_str ("not an action"));
+      _LOG_ERROR ("not an action");
+      return ActionItemPtr ();
     }
-  Name deviceName = name.getPartialName (3, name.size ()-4);
+
+  string appName = name.getCompFromBackAsString (3);
+  if (appName != m_appName)
+    {
+      _LOG_ERROR ("Action doesn't belong to this application");
+      return ActionItemPtr ();
+    }
+
+  Name deviceName = name.getPartialName (0, name.size ()-4);
 
   _LOG_DEBUG ("From [" << name << "] extracted deviceName: " << deviceName << ", sharedFolder: " << sharedFolder << ", seqno: " << seqno);
 
diff --git a/src/content-server.cc b/src/content-server.cc
index 2aa19ca..fa0ea4c 100644
--- a/src/content-server.cc
+++ b/src/content-server.cc
@@ -62,11 +62,7 @@
   ScopedLock lock (m_mutex);
   for (PrefixIt it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
   {
-    Name filePrefix   = Name (*it)(m_appName)("file");
-    Name actionPrefix = Name (*it)(m_appName)(m_sharedFolderName)("action");
-
-    m_ccnx->clearInterestFilter(filePrefix);
-    m_ccnx->clearInterestFilter(actionPrefix);
+    m_ccnx->clearInterestFilter (*it);
   }
 
   m_prefixes.clear ();
@@ -75,17 +71,11 @@
 void
 ContentServer::registerPrefix(const Name &forwardingHint)
 {
-  // Format for files:   /<forwarding-hint>/<appname>/file/<hash>/<device_name>/<segment>
-  // Format for actions: /<forwarding-hint>/<appname>/<shared-folder>/action/<device_name>/<action-seq>
+  // Format for files:   /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
+  // Format for actions: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
 
-  Name filePrefix   = Name (forwardingHint)(m_appName)("file");
-  Name actionPrefix = Name (forwardingHint)(m_appName)(m_sharedFolderName)("action");
-
-  m_ccnx->setInterestFilter (filePrefix,   bind(&ContentServer::serve_File,   this, forwardingHint, filePrefix,   _1));
-  m_ccnx->setInterestFilter (actionPrefix, bind(&ContentServer::serve_Action, this, forwardingHint, actionPrefix, _1));
-
-  _LOG_DEBUG (">> content server: register FILE   " << filePrefix);
-  _LOG_DEBUG (">> content server: register ACTION " << actionPrefix);
+  _LOG_DEBUG (">> content server: register " << forwardingHint);
+  m_ccnx->setInterestFilter (forwardingHint, bind(&ContentServer::filterAndServe, this, forwardingHint, _1));
 
   ScopedLock lock (m_mutex);
   m_prefixes.insert(forwardingHint);
@@ -94,70 +84,66 @@
 void
 ContentServer::deregisterPrefix (const Name &forwardingHint)
 {
-  Name filePrefix   = Name (forwardingHint)(m_appName)("file");
-  Name actionPrefix = Name (forwardingHint)(m_appName)(m_sharedFolderName)("action");
-
-  m_ccnx->clearInterestFilter(filePrefix);
-  m_ccnx->clearInterestFilter(actionPrefix);
-
-  _LOG_DEBUG ("<< content server: deregister FILE   " << filePrefix);
-  _LOG_DEBUG ("<< content server: deregister ACTION " << actionPrefix);
+  _LOG_DEBUG ("<< content server: deregister " << forwardingHint);
+  m_ccnx->clearInterestFilter(forwardingHint);
 
   ScopedLock lock (m_mutex);
   m_prefixes.erase (forwardingHint);
 }
 
-// void
-// ContentServer::serve(Name forwardingHint, const Name &interest)
-// {
-//   // /forwardingHint/app-name/device-name/action/shared-folder/action-seq
-//   // /forwardingHint/app-name/device-name/file/file-hash/segment
+void
+ContentServer::filterAndServe (Name forwardingHint, const Name &interest)
+{
+  // Format for files:   /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
+  // Format for actions: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
 
-//   Name name = interest.getPartialName(forwardingHint.size());
-//   if (name.size() > 3)
-//   {
-//     string type = name.getCompAsString(name.size() - 3);
-//     if (type == "action")
-//     {
-//       serve_Action (forwardingHint, interest);
-//     }
-//     else if (type == "file")
-//     {
-//       serve_File (forwardingHint, interest);
-//     }
-//   }
-// }
+  Name name = interest.getPartialName (forwardingHint.size());
+  // name for files:   /<device_name>/<appname>/file/<hash>/<segment>
+  // name for actions: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
+
+  if (name.size() >= 4 && name.getCompFromBackAsString (3) == m_appName)
+  {
+    string type = name.getCompFromBackAsString (2);
+    if (type == "file")
+      {
+        serve_File (forwardingHint, interest);
+      }
+    else if (type == "action")
+      {
+        serve_Action (forwardingHint, interest);
+      }
+  }
+}
 
 void
-ContentServer::serve_Action (Name forwardingHint, Name locatorPrefix, Name interest)
+ContentServer::serve_Action (Name forwardingHint, Name interest)
 {
-  _LOG_DEBUG (">> content server serving ACTION, hint: " << forwardingHint << ", locatorPrefix: " << locatorPrefix << ", interest: " << interest);
-  m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_Action_Execute, this, forwardingHint, locatorPrefix, interest), boost::lexical_cast<string>(interest));
+  _LOG_DEBUG (">> content server serving ACTION, hint: " << forwardingHint << ", interest: " << interest);
+  m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_Action_Execute, this, forwardingHint, interest), boost::lexical_cast<string>(interest));
   // need to unlock ccnx mutex... or at least don't lock it
 }
 
 void
-ContentServer::serve_File (Name forwardingHint, Name locatorPrefix, Name interest)
+ContentServer::serve_File (Name forwardingHint, Name interest)
 {
-  _LOG_DEBUG (">> content server serving FILE, hint: " << forwardingHint << ", locatorPrefix: " << locatorPrefix << ", interest: " << interest);
+  _LOG_DEBUG (">> content server serving FILE, hint: " << forwardingHint << ", interest: " << interest);
 
-  m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_File_Execute, this, forwardingHint, locatorPrefix, interest), boost::lexical_cast<string>(interest));
+  m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_File_Execute, this, forwardingHint, interest), boost::lexical_cast<string>(interest));
   // need to unlock ccnx mutex... or at least don't lock it
 }
 
 void
-ContentServer::serve_File_Execute (Name forwardingHint, Name locatorPrefix, Name interest)
+ContentServer::serve_File_Execute (Name forwardingHint, Name interest)
 {
   // forwardingHint: /<forwarding-hint>
-  // locatorPrefix:  /<forwarding-hint>/<appname>/file
-  // interest:       /<forwarding-hint>/<appname>/file/<hash>/<device_name>/<segment>
+  // interest:       /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
 
-  Name pureInterest = interest.getPartialName (locatorPrefix.size ());
-  // pureInterest:   /<hash>/<device_name>/<segment>
+  Name name = interest.getPartialName (forwardingHint.size());
+  // name:           /<device_name>/<appname>/file/<hash>/<segment>
 
-  int64_t segment = pureInterest.getCompFromBackAsInt (0);
-  Name deviceName = pureInterest.getPartialName (1, pureInterest.size () - 2);
-  Hash hash (head(pureInterest.getComp (0)), pureInterest.getComp (0).size());
+  int64_t segment = name.getCompFromBackAsInt (0);
+  Name deviceName = name.getPartialName (0, name.size () - 4);
+  Hash hash (head(name.getCompFromBack (1)), name.getCompFromBack (1).size());
 
   _LOG_DEBUG (" server FILE for device: " << deviceName << ", file_hash: " << hash.shortHash () << " segment: " << segment);
 
@@ -218,17 +204,16 @@
 }
 
 void
-ContentServer::serve_Action_Execute (Name forwardingHint, Name locatorPrefix, Name interest)
+ContentServer::serve_Action_Execute (Name forwardingHint, Name interest)
 {
   // forwardingHint: /<forwarding-hint>
-  // locatorPrefix:  /<forwarding-hint>/<appname>/<shared-folder>/action
-  // interest:       /<forwarding-hint>/<appname>/<shared-folder>/action/<device_name>/<action-seq>
+  // interest:       /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
 
-  Name pureInterest = interest.getPartialName (locatorPrefix.size ());
-  // pureInterest:  /<device_name>/<action-seq>
+  Name name = interest.getPartialName (forwardingHint.size());
+  // name for actions: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
 
-  int64_t seqno = pureInterest.getCompFromBackAsInt (0);
-  Name deviceName = pureInterest.getPartialName (0, pureInterest.size () - 1);
+  int64_t seqno = name.getCompFromBackAsInt (0);
+  Name deviceName = name.getPartialName (0, name.size () - 4);
 
   _LOG_DEBUG (" server ACTION for device: " << deviceName << " and seqno: " << seqno);
 
diff --git a/src/content-server.h b/src/content-server.h
index 7d9b3ed..13ca2dc 100644
--- a/src/content-server.h
+++ b/src/content-server.h
@@ -47,20 +47,20 @@
   void deregisterPrefix(const Ccnx::Name &prefix);
 
 private:
-  // void
-  // serve (Ccnx::Name forwardingHint, const Ccnx::Name &interest);
+  void
+  filterAndServe (Ccnx::Name forwardingHint, const Ccnx::Name &interest);
 
   void
-  serve_Action (Ccnx::Name forwardingHint, Ccnx::Name locatorPrefix, Ccnx::Name interest);
+  serve_Action (Ccnx::Name forwardingHint, Ccnx::Name interest);
 
   void
-  serve_File (Ccnx::Name forwardingHint, Ccnx::Name locatorPrefix, Ccnx::Name interest);
+  serve_File (Ccnx::Name forwardingHint, Ccnx::Name interest);
 
   void
-  serve_Action_Execute(Ccnx::Name forwardingHint, Ccnx::Name locatorPrefix, Ccnx::Name interest);
+  serve_Action_Execute(Ccnx::Name forwardingHint, Ccnx::Name interest);
 
   void
-  serve_File_Execute(Ccnx::Name forwardingHint, Ccnx::Name locatorPrefix, Ccnx::Name interest);
+  serve_File_Execute(Ccnx::Name forwardingHint, Ccnx::Name interest);
 
   void
   flushStaleDbCache();
diff --git a/src/dispatcher.cc b/src/dispatcher.cc
index 38ba37e..fadc224 100644
--- a/src/dispatcher.cc
+++ b/src/dispatcher.cc
@@ -270,7 +270,7 @@
       Name userName (reinterpret_cast<const unsigned char *> (state.name ().c_str ()), state.name ().size ());
 
       // fetch actions with oldSeq + 1 to newSeq (inclusive)
-      Name actionNameBase = Name ("/")(CHRONOSHARE_APP)(m_sharedFolder)("action")(userName);
+      Name actionNameBase = Name ("/")(userName)(CHRONOSHARE_APP)("action")(m_sharedFolder);
 
       m_actionFetcher->Enqueue (userName, actionNameBase,
                                 std::max<uint64_t> (oldSeq + 1, 1), newSeq, FetchManager::PRIORITY_HIGH);
@@ -286,13 +286,18 @@
   _LOG_DEBUG ("Received action deviceName: " << deviceName << ", actionBaseName: " << actionBaseName << ", seqno: " << seqno);
 
   ActionItemPtr action = m_actionLog->AddRemoteAction (deviceName, seqno, actionPco);
+  if (!action)
+    {
+      _LOG_ERROR ("AddRemoteAction did not insert action, ignoring");
+      return;
+    }
   // trigger may invoke Did_ActionLog_ActionApply_Delete or Did_ActionLog_ActionApply_AddOrModify callbacks
 
   if (action->action () == ActionItem::UPDATE)
     {
       Hash hash (action->file_hash ().c_str(), action->file_hash ().size ());
 
-      Name fileNameBase = Name ("/")(CHRONOSHARE_APP)("file")(hash.GetHash (), hash.GetHashBytes ())(deviceName);
+      Name fileNameBase = Name ("/")(deviceName)(CHRONOSHARE_APP)("file")(hash.GetHash (), hash.GetHashBytes ());
 
       string hashStr = lexical_cast<string> (hash);
       if (ObjectDb::DoesExist (m_rootDir / ".chronoshare",  deviceName, hashStr))
@@ -344,7 +349,9 @@
 void
 Dispatcher::Did_FetchManager_FileSegmentFetch_Execute (Ccnx::Name deviceName, Ccnx::Name fileSegmentBaseName, uint32_t segment, Ccnx::PcoPtr fileSegmentPco)
 {
-  const Bytes &hashBytes = fileSegmentBaseName.getComp (2);
+  // fileSegmentBaseName:  /<device_name>/<appname>/file/<hash>
+
+  const Bytes &hashBytes = fileSegmentBaseName.getCompFromBack (0);
   Hash hash (head(hashBytes), hashBytes.size());
 
   _LOG_DEBUG ("Received segment deviceName: " << deviceName << ", segmentBaseName: " << fileSegmentBaseName << ", segment: " << segment);
@@ -374,11 +381,13 @@
 void
 Dispatcher::Did_FetchManager_FileFetchComplete_Execute (Ccnx::Name deviceName, Ccnx::Name fileBaseName)
 {
+  // fileBaseName:  /<device_name>/<appname>/file/<hash>
+
   _LOG_DEBUG ("Finished fetching " << deviceName << ", fileBaseName: " << fileBaseName);
 
-  const Bytes &hashBytes = fileBaseName.getComp (2);
+  const Bytes &hashBytes = fileBaseName.getCompFromBack (0);
   Hash hash (head (hashBytes), hashBytes.size ());
-  _LOG_DEBUG ("Extracted hash: " << hash);
+  _LOG_DEBUG ("Extracted hash: " << hash.shortHash ());
 
   if (m_objectDbMap.find (hash) != m_objectDbMap.end())
   {
diff --git a/src/object-manager.cc b/src/object-manager.cc
index 7b02e16..fc50488 100644
--- a/src/object-manager.cc
+++ b/src/object-manager.cc
@@ -54,7 +54,7 @@
 {
 }
 
-// /<appname>/file/<hash>/<devicename>/<segment>
+// /<devicename>/<appname>/file/<hash>/<segment>
 boost::tuple<HashPtr /*object-db name*/, size_t /* number of segments*/>
 ObjectManager::localFileToObjects (const fs::path &file, const Ccnx::Name &deviceName)
 {
@@ -73,7 +73,7 @@
           break;
         }
 
-      Name name = Name ("/")(m_appName)("file")(fileHash->GetHash (), fileHash->GetHashBytes ())(deviceName)(segment);
+      Name name = Name ("/")(deviceName)(m_appName)("file")(fileHash->GetHash (), fileHash->GetHashBytes ())(segment);
 
       // cout << *fileHash << endl;
       // cout << name << endl;
diff --git a/test/test-action-log.cc b/test/test-action-log.cc
index 1a1ff1f..c4d6a9b 100644
--- a/test/test-action-log.cc
+++ b/test/test-action-log.cc
@@ -77,12 +77,12 @@
   pco = actionLog->LookupActionPco (localName, 1);
   BOOST_CHECK_EQUAL ((bool)pco, true);
 
-  BOOST_CHECK_EQUAL (pco->name (), "/test-chronoshare/top-secret/action/alex/%00%01");
+  BOOST_CHECK_EQUAL (pco->name (), "/alex/test-chronoshare/action/top-secret/%00%01");
 
-  ActionItemPtr action = actionLog->LookupAction (Name ("/test-chronoshare/top-secret/action/alex")(0));
+  ActionItemPtr action = actionLog->LookupAction (Name ("/alex/test-chronoshare/action/top-secret")(0));
   BOOST_CHECK_EQUAL ((bool)action, false);
 
-  action = actionLog->LookupAction (Name ("/test-chronoshare/top-secret/action/alex")(1));
+  action = actionLog->LookupAction (Name ("/alex/test-chronoshare/action/top-secret")(1));
   BOOST_CHECK_EQUAL ((bool)action, true);
 
   if (action)
@@ -117,7 +117,7 @@
       BOOST_CHECK_EQUAL (action->version (), 1);
     }
 
-  BOOST_CHECK_NO_THROW (actionLog->AddRemoteAction (pco));
+  BOOST_CHECK_EQUAL ((bool)actionLog->AddRemoteAction (pco), true);
   BOOST_CHECK_EQUAL (actionLog->LogSize (), 2);
 
   // create a real remote action
@@ -128,11 +128,11 @@
   item.set_timestamp (time (NULL));
 
   BytesPtr item_msg = serializeMsg (item);
-  Name actionName = Name ("/")("test-chronoshare")("top-secret")("action")("zhenkai")(1);
+  Name actionName = Name ("/")(Name("/zhenkai/test"))("test-chronoshare")("action")("top-secret")(1);
   Bytes actionData = ccnx->createContentObject (actionName, head (*item_msg), item_msg->size ());
 
   pco = make_shared<ParsedContentObject> (actionData);
-  BOOST_CHECK_NO_THROW (actionLog->AddRemoteAction (pco));
+  BOOST_CHECK_EQUAL ((bool)actionLog->AddRemoteAction (pco), true);
   BOOST_CHECK_EQUAL (actionLog->LogSize (), 3);
 
   remove_all (tmpdir);
diff --git a/test/test-serve-and-fetch.cc b/test/test-serve-and-fetch.cc
index 9d71cfb..7919246 100644
--- a/test/test-serve-and-fetch.cc
+++ b/test/test-serve-and-fetch.cc
@@ -147,7 +147,7 @@
 
   FetchManager fm(ccnx_fetch, bind(simpleMap, _1));
   HashPtr hash = pub.get<0> ();
-  Name baseName = Name ("/")(APPNAME)("file")(hash->GetHash(), hash->GetHashBytes())(deviceName);
+  Name baseName = Name ("/")(deviceName)(APPNAME)("file")(hash->GetHash(), hash->GetHashBytes());
 
   fm.Enqueue(deviceName, baseName, bind(segmentCallback, _1, _2, _3, _4), bind(finishCallback, _1, _2), 0, pub.get<1>() - 1);