From 235e64ef446b66e42d0d703707948ab29b14b8e8 Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Wed, 25 Feb 2015 11:08:10 +0100
Subject: [PATCH] Adapted the existing object code to the backend interface.

---
 objectstore/Agent.cpp                         | 144 ++++--------------
 objectstore/Agent.hpp                         |  54 ++-----
 objectstore/AgentRegister.cpp                 |  31 ++--
 ...ckendAbstractTests.cpp => BackendTest.cpp} |  27 +++-
 ...ckendAbstractTests.hpp => BackendTest.hpp} |   0
 objectstore/BackendVFSTest.cpp                |  31 ----
 objectstore/CMakeLists.txt                    |  11 +-
 objectstore/ObjectOps.hpp                     |  31 ++--
 objectstore/ObjectStoreChoice.hpp             |   9 --
 objectstore/RootEntry.cpp                     |  26 ++--
 objectstore/RootEntryTest.cpp                 |   8 +-
 11 files changed, 130 insertions(+), 242 deletions(-)
 rename objectstore/{BackendAbstractTests.cpp => BackendTest.cpp} (66%)
 rename objectstore/{BackendAbstractTests.hpp => BackendTest.hpp} (100%)
 delete mode 100644 objectstore/BackendVFSTest.cpp
 delete mode 100644 objectstore/ObjectStoreChoice.hpp

diff --git a/objectstore/Agent.cpp b/objectstore/Agent.cpp
index 1a0d52e577..79e72b97f0 100644
--- a/objectstore/Agent.cpp
+++ b/objectstore/Agent.cpp
@@ -1,19 +1,21 @@
 #include "Agent.hpp"
 #include "AgentRegister.hpp"
 #include "RootEntry.hpp"
+#include "exception/Errnum.hpp"
 #include <string>
 #include <sstream>
+#include <iomanip>
 #include <sys/syscall.h>
 #include <ctime>
 #include <cxxabi.h>
 
-cta::objectstore::Agent::Agent(ObjectStore & os): 
+cta::objectstore::Agent::Agent(Backend & os): 
   ObjectOps<serializers::Agent>(os), 
-  m_setupDone(false), m_creationDone(false), m_observerVersion(false), m_nextId(0) {}
+  m_setupDone(false), m_creationDone(false), m_nextId(0) {}
 
-cta::objectstore::Agent::Agent(ObjectStore & os, const std::string & typeName): 
+cta::objectstore::Agent::Agent(Backend & os, const std::string & typeName): 
   ObjectOps<serializers::Agent>(os), 
-  m_setupDone(false), m_creationDone(false), m_observerVersion(false), m_nextId(0) {
+  m_setupDone(false), m_creationDone(false), m_nextId(0) {
   setup(typeName);
 }
 
@@ -47,8 +49,7 @@ void cta::objectstore::Agent::create() {
   AgentRegister ar(re.allocateOrGetAgentRegister(*this), *this);
   ar.addIntendedElement(selfName(), *this);
   serializers::Agent as;
-  as.set_name(selfName());
-  as.set_heartbeatcount(0);
+  as.set_heartbeat(0);
   writeChild(selfName(), as);
   ar.upgradeIntendedElementToActual(selfName(), *this);
   m_creationDone = true;
@@ -66,17 +67,8 @@ std::string cta::objectstore::Agent::name() {
   return selfName();
 }
 
-void cta::objectstore::Agent::flushContexts() {
-  for(size_t i=0; i< c_handleCount; i++) {
-    m_contexts[i].release();
-  }
-}
-
 cta::objectstore::Agent::~Agent() {
-  for (size_t i=0; i < c_handleCount; i++) {
-    m_contexts[i].release();
-  }
-  if (m_creationDone && !m_observerVersion) {
+  if (m_creationDone) {
     try {
       remove();
       RootEntry re(*this);
@@ -90,142 +82,70 @@ cta::objectstore::Agent::~Agent() {
 std::string cta::objectstore::Agent::nextId(const std::string & childType) {
   if (!m_setupDone)
     throw SetupNotDone("In Agent::nextId(): setup() not yet done");
-  if (m_observerVersion)
-    throw ObserverOnly("In Agent::nextId(): this object is observer only");
   std::stringstream id;
   id << childType << "-" << name() << "-" << m_nextId++;
   return id.str();
 }
 
-cta::objectstore::ContextHandle & 
-  cta::objectstore::Agent::getFreeContext() {
-  for (size_t i=0; i < c_handleCount; i++) {
-    if (!m_contexts[i].isSet())
-      return m_contexts[i];
-  }
-  throw cta::exception::Exception("Could not find free context slot");
-}
-
-void cta::objectstore::Agent::addToIntend (std::string container, std::string name, serializers::ObjectType objectType) {
-  if (!m_creationDone)
-    throw CreationNotDone("In Agent::addToIntend(): creation() not yet done");
-  serializers::Agent as;
-  ContextHandle & ctx = getFreeContext();
-  lockExclusiveAndRead(as, ctx, "Agent::addToIntend");
-  serializers::ObjectCreationIntent * oca = 
-    as.mutable_creationintent()->Add();
-  oca->set_container(container);
-  oca->set_name(name);
-  oca->set_type(objectType);
-  write(as);
-  unlock(ctx, "Agent::addToIntend");
-}
-
-void cta::objectstore::Agent::removeFromIntent (std::string container, std::string name, serializers::ObjectType objectType) {
-  if (!m_creationDone)
-    throw CreationNotDone("In Agent::removeFromIntent(): creation() not yet done");
-  serializers::Agent as;
-  ContextHandle & ctx = getFreeContext();
-  lockExclusiveAndRead(as, ctx, "Agent::removeFromIntent");
-  bool found;
-  do {
-    found = false;
-    for (int i=0; i<as.mutable_creationintent()->size(); i++) {
-      if (container == as.mutable_creationintent(i)->container() &&
-          name == as.mutable_creationintent(i)->name() &&
-          objectType == as.mutable_creationintent(i)->type()) {
-        found = true;
-        as.mutable_creationintent()->SwapElements(i, as.creationintent_size()-1);
-        as.mutable_creationintent()->RemoveLast();
-        break;
-      }
-    }
-  } while (found);
-  write(as);
-  unlock(ctx, "Agent::removeFromIntent");
-}
-
-void cta::objectstore::Agent::addToOwnership(std::string name, serializers::ObjectType objectType) {
+void cta::objectstore::Agent::addToOwnership(std::string name) {
   if (!m_creationDone)
     throw CreationNotDone("In Agent::addToOwnership(): creation() not yet done");
   serializers::Agent as;
-  ContextHandle & ctx = getFreeContext();
-  lockExclusiveAndRead(as, ctx, __func__);
-  serializers::ObjectOwnershipIntent * ooi = 
-    as.mutable_ownershipintent()->Add();
-  ooi->set_name(name);
-  ooi->set_type(objectType);
+  lockExclusiveAndRead(as);
+  std::string * owned = as.mutable_ownedobjects()->Add();
+  *owned = name;
   write(as);
-  unlock(ctx);
+  unlock();
 }
 
-void cta::objectstore::Agent::removeFromOwnership(std::string name, serializers::ObjectType objectType) {
+void cta::objectstore::Agent::removeFromOwnership(std::string name) {
   if (!m_creationDone)
     throw CreationNotDone("In Agent::removeFromOwnership(): creation() not yet done");
   serializers::Agent as;
-  ContextHandle & ctx = getFreeContext();
-  lockExclusiveAndRead(as, ctx, __func__);
+  lockExclusiveAndRead(as);
   bool found;
   do {
     found = false;
-    for (int i=0; i<as.mutable_ownershipintent()->size(); i++) {
-      if (name == as.mutable_ownershipintent(i)->name() &&
-          objectType == as.mutable_ownershipintent(i)->type()) {
+    for (int i=0; i<as.mutable_ownedobjects()->size(); i++) {
+      if (name == *as.mutable_ownedobjects(i)) {
         found = true;
-        as.mutable_ownershipintent()->SwapElements(i, as.ownershipintent_size()-1);
-        as.mutable_ownershipintent()->RemoveLast();
+        as.mutable_ownedobjects()->SwapElements(i, as.mutable_ownedobjects()->size()-1);
+        as.mutable_ownedobjects()->RemoveLast();
         break;
       }
     }
   } while (found);
   write(as);
-  unlock(ctx);
+  unlock();
 }
 
-std::list<cta::objectstore::Agent::intentEntry> 
-  cta::objectstore::Agent::getIntentLog() {
-  if (!m_creationDone)
-    throw CreationNotDone("In Agent::getIntentLog(): creation() not yet done");
-  serializers::Agent as;
-  updateFromObjectStore(as, getFreeContext());
-  std::list<intentEntry> ret;
-  for (int i=0; i<as.creationintent_size(); i++) {
-    ret.push_back(intentEntry(as.creationintent(i).container(),
-                              as.creationintent(i).name(),
-                              as.creationintent(i).type()));
-  }
-  return ret;
-}
-
-std::list<cta::objectstore::Agent::ownershipEntry>
+std::list<std::string> 
   cta::objectstore::Agent::getOwnershipLog() {
   if (!m_creationDone)
-    throw CreationNotDone("In Agent::getOwnershipLog(): creation() not yet done");
+    throw CreationNotDone("In Agent::getIntentLog(): creation() not yet done");
   serializers::Agent as;
-  updateFromObjectStore(as, getFreeContext());
-  std::list<ownershipEntry> ret;
-  for (int i=0; i<as.creationintent_size(); i++) {
-    ret.push_back(ownershipEntry(as.creationintent(i).name(),
-                                 as.creationintent(i).type()));
+  updateFromObjectStore(as);
+  std::list<std::string> ret;
+  for (int i=0; i<as.ownedobjects_size(); i++) {
+    ret.push_back(as.ownedobjects(i));
   }
   return ret;
 }
 
-cta::objectstore::ObjectStore & cta::objectstore::Agent::objectStore() {
+cta::objectstore::Backend & cta::objectstore::Agent::objectStore() {
   return ObjectOps<serializers::Agent>::objectStore();
 }
 
 void cta::objectstore::Agent::heartbeat(Agent& agent) {
-  ContextHandle & context = agent.getFreeContext();
   serializers::Agent as;
-  lockExclusiveAndRead(as, context, __func__);
-  as.set_heartbeatcount(as.heartbeatcount()+1);
+  lockExclusiveAndRead(as);
+  as.set_heartbeat(as.heartbeat()+1);
   write(as);
-  unlock(context);
+  unlock();
 }
 
 uint64_t cta::objectstore::Agent::getHeartbeatCount(Agent& agent) {
   serializers::Agent as;
-  updateFromObjectStore(as, agent.getFreeContext());
-  return as.heartbeatcount();
+  updateFromObjectStore(as);
+  return as.heartbeat();
 }
diff --git a/objectstore/Agent.hpp b/objectstore/Agent.hpp
index fa7e7f2fbe..fe2d2f1113 100644
--- a/objectstore/Agent.hpp
+++ b/objectstore/Agent.hpp
@@ -1,10 +1,10 @@
 #pragma once
 
-#include "ObjectStoreChoice.hpp"
 #include "ObjectOps.hpp"
 #include "objectstore/cta.pb.h"
 #include "utils/Timer.hpp"
 #include <cxxabi.h>
+#include <list>
 
 namespace cta { namespace objectstore {
 
@@ -19,9 +19,9 @@ namespace cta { namespace objectstore {
 
 class Agent: protected ObjectOps<serializers::Agent> {
 public:
-  Agent(ObjectStore & os);
+  Agent(Backend & os);
   
-  Agent(ObjectStore & os, const std::string & typeName);
+  Agent(Backend & os, const std::string & typeName);
   
   void setup(const std::string & typeName);
   
@@ -52,18 +52,16 @@ public:
   
   std::string nextId(const std::string & childType);
   
-  ContextHandle & getFreeContext();
-  
   class ScopedIntent {
   public:
     ScopedIntent(Agent & agent, std::string container, std::string name, serializers::ObjectType objectType):
     m_agent(agent), m_container(container), m_name(name), m_objectType(objectType), m_present(false) {
-      m_agent.addToIntend(m_container, m_name, m_objectType);
+      m_agent.addToOwnership(m_name);
       m_present = true;
     }
     void removeFromIntent() {
       if(!m_present) return;
-      m_agent.removeFromIntent(m_container, m_name, m_objectType);
+      m_agent.removeFromOwnership(m_name);
       m_present = false;
     }
     ~ScopedIntent() {
@@ -82,14 +80,14 @@ public:
   
   class ScopedOwnership {
   public:
-    ScopedOwnership(Agent & agent, std::string name, serializers::ObjectType objectType):
-    m_agent(agent), m_name(name), m_objectType(objectType), m_present(false) {
-      m_agent.addToOwnership(m_name, m_objectType);
+    ScopedOwnership(Agent & agent, std::string name):
+    m_agent(agent), m_name(name), m_present(false) {
+      m_agent.addToOwnership(m_name);
       m_present = true;
     }
     void removeFromOwnership() {
       if(!m_present) return;
-      m_agent.removeFromOwnership( m_name, m_objectType);
+      m_agent.removeFromOwnership( m_name);
       m_present = false;
     }
     ~ScopedOwnership() {
@@ -101,41 +99,24 @@ public:
   private:
     Agent & m_agent;
     std::string m_name;
-    serializers::ObjectType m_objectType;
     bool m_present;
   };
   
-  void addToIntend (std::string container, std::string name, serializers::ObjectType objectType);
-  
-  void removeFromIntent (std::string container, std::string name, serializers::ObjectType objectType);
-  
-  void addToOwnership(std::string name, serializers::ObjectType objectType);
+  void addToOwnership(std::string name);
   
-  void removeFromOwnership(std::string name, serializers::ObjectType objectType);
+  void removeFromOwnership(std::string name);
   
-  class intentEntry {
+  class ownedObject {
   public:
-    intentEntry(const std::string & c,
-                const std::string & n,
-                serializers::ObjectType t):container(c), name(n), objectType(t) {}
+    ownedObject(const std::string & c,
+                const std::string & n):container(c), name(n) {}
     std::string container;
     std::string name;
-    serializers::ObjectType objectType;
   };
-    
-  class ownershipEntry {
-  public:
-    ownershipEntry(const std::string & n,
-                   serializers::ObjectType t):name(n), objectType(t) {}
-    std::string name;
-    serializers::ObjectType objectType;
-  };
-  
-  std::list<intentEntry> getIntentLog();
   
-  std::list<ownershipEntry> getOwnershipLog();
+  std::list<std::string> getOwnershipLog();
   
-  ObjectStore & objectStore();
+  Backend & objectStore();
   
   std::string dump(Agent & agent);
   
@@ -147,10 +128,7 @@ private:
   std::string m_typeName;
   bool m_setupDone;
   bool m_creationDone;
-  bool m_observerVersion;
   uint64_t m_nextId;
-  static const size_t c_handleCount = 100;
-  ContextHandle m_contexts[c_handleCount];
 };
   
 }}
\ No newline at end of file
diff --git a/objectstore/AgentRegister.cpp b/objectstore/AgentRegister.cpp
index 992c2558f4..e8506f2106 100644
--- a/objectstore/AgentRegister.cpp
+++ b/objectstore/AgentRegister.cpp
@@ -5,22 +5,20 @@ ObjectOps<serializers::AgentRegister>(agent.objectStore(), name) {
   // Check that the entry is present and readable (depending on implementation
   // of object store, locking might or might not succeed)
   serializers::AgentRegister rs;
-  updateFromObjectStore(rs, agent.getFreeContext());
+  updateFromObjectStore(rs);
 }
 
 void cta::objectstore::AgentRegister::addElement (std::string name, Agent & agent) {
   serializers::AgentRegister rs;
-  ContextHandle & context = agent.getFreeContext();
-  lockExclusiveAndRead(rs, context, __func__);
+  lockExclusiveAndRead(rs);
   rs.add_elements(name);
   write(rs);
-  unlock(context);
+  unlock();
 }
 
 void cta::objectstore::AgentRegister::removeElement (const std::string  & name, Agent & agent) {
   serializers::AgentRegister rs;
-  ContextHandle & context = agent.getFreeContext();
-  lockExclusiveAndRead(rs, context, __func__);
+  lockExclusiveAndRead(rs);
   bool found;
   do {
     found = false;
@@ -34,22 +32,20 @@ void cta::objectstore::AgentRegister::removeElement (const std::string  & name,
     }
   } while (found);
   write(rs);
-  unlock(context);
+  unlock();
 }
 
 void cta::objectstore::AgentRegister::addIntendedElement(std::string name, Agent& agent) {
   serializers::AgentRegister rs;
-  ContextHandle & context = agent.getFreeContext();
-  lockExclusiveAndRead(rs, context, __func__);
+  lockExclusiveAndRead(rs);
   rs.add_intendedelements(name);
   write(rs);
-  unlock(context);
+  unlock();
 }
 
 void cta::objectstore::AgentRegister::upgradeIntendedElementToActual(std::string name, Agent& agent) {
   serializers::AgentRegister rs;
-  ContextHandle & context = agent.getFreeContext();
-  lockExclusiveAndRead(rs, context, __func__);
+  lockExclusiveAndRead(rs);
   bool found;
   do {
     found = false;
@@ -64,14 +60,13 @@ void cta::objectstore::AgentRegister::upgradeIntendedElementToActual(std::string
   } while (found);
   rs.add_elements(name);
   write(rs);
-  unlock(context);
+  unlock();
 }
 
 
 void cta::objectstore::AgentRegister::removeIntendedElement(const std::string& name, Agent& agent) {
   serializers::AgentRegister rs;
-  ContextHandle & context = agent.getFreeContext();
-  lockExclusiveAndRead(rs, context, __func__);
+  lockExclusiveAndRead(rs);
   bool found;
   do {
     found = false;
@@ -85,14 +80,14 @@ void cta::objectstore::AgentRegister::removeIntendedElement(const std::string& n
     }
   } while (found);
   write(rs);
-  unlock(context);
+  unlock();
 }
 
 
 
 std::list<std::string> cta::objectstore::AgentRegister::getElements(Agent & agent) {
   serializers::AgentRegister rs;
-  updateFromObjectStore(rs, agent.getFreeContext());
+  updateFromObjectStore(rs);
   std::list<std::string> ret;
   for (int i=0; i<rs.elements_size(); i++) {
     ret.push_back(rs.elements(i));
@@ -102,7 +97,7 @@ std::list<std::string> cta::objectstore::AgentRegister::getElements(Agent & agen
 
 std::string cta::objectstore::AgentRegister::dump(Agent & agent) {
   serializers::AgentRegister rs;
-  updateFromObjectStore(rs, agent.getFreeContext());
+  updateFromObjectStore(rs);
   std::stringstream ret;
   ret<< "<<<< AgentRegister " << selfName() << " dump start" << std::endl
     << "Array size=" << rs.elements_size() << std::endl;
diff --git a/objectstore/BackendAbstractTests.cpp b/objectstore/BackendTest.cpp
similarity index 66%
rename from objectstore/BackendAbstractTests.cpp
rename to objectstore/BackendTest.cpp
index 17fc1842de..598ccdf912 100644
--- a/objectstore/BackendAbstractTests.cpp
+++ b/objectstore/BackendTest.cpp
@@ -1,4 +1,4 @@
-#include "BackendAbstractTests.hpp"
+#include "BackendTest.hpp"
 #include "BackendVFS.hpp"
 #include "BackendRados.hpp"
 #include "exception/Exception.hpp"
@@ -31,6 +31,31 @@ TEST_P(BackendAbstractTest, BasicReadWrite) {
   ASSERT_EQ(false, m_os->exists(testObjectName));
 }
 
+TEST_P(BackendAbstractTest, LockingInterface) {
+  std::cout << "Type=" << m_os->typeName() << std::endl;
+  const std::string testObjectName = "testObject";
+  m_os->create(testObjectName, "");
+  {
+    // If we don't scope the object, the release will blow up after
+    // removal of the file.
+    std::auto_ptr<cta::objectstore::Backend::ScopedLock> lock( 
+      m_os->lockExclusive(testObjectName));
+  }
+  {
+    std::auto_ptr<cta::objectstore::Backend::ScopedLock> lock( 
+      m_os->lockExclusive(testObjectName));
+    lock->release();
+  }
+  m_os->remove(testObjectName);
+}
+
+TEST_P(BackendAbstractTest, ParametersInterface) {
+  std::cout << "Type=" << m_os->typeName() << std::endl;
+  std::auto_ptr<cta::objectstore::Backend::Parameters> params(
+    m_os->getParams());
+  std::cout << params->toStr() << std::endl;
+}
+
 cta::objectstore::BackendVFS osVFS;
 cta::objectstore::BackendRados osRados("tapetest", "tapetest");
 INSTANTIATE_TEST_CASE_P(BackendTest, BackendAbstractTest, ::testing::Values(&osVFS, &osRados));
diff --git a/objectstore/BackendAbstractTests.hpp b/objectstore/BackendTest.hpp
similarity index 100%
rename from objectstore/BackendAbstractTests.hpp
rename to objectstore/BackendTest.hpp
diff --git a/objectstore/BackendVFSTest.cpp b/objectstore/BackendVFSTest.cpp
deleted file mode 100644
index afb198b9ba..0000000000
--- a/objectstore/BackendVFSTest.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <gtest/gtest.h>
-#include "BackendVFS.hpp"
-#include "exception/Exception.hpp"
-
-namespace unitTests {
-  TEST(BackendVFS, BasicReadWrite) {
-    cta::objectstore::BackendVFS bvfs;
-    const std::string testValue = "1234";
-    const std::string testSecondValue = "1234";
-    const std::string testObjectName = "testObject";
-    // Check we can verify the absence of an object
-    ASSERT_EQ(false, bvfs.exists(testObjectName));
-    // Check that an update attempt fails on a non-existing object
-    ASSERT_THROW(bvfs.atomicOverwrite(testObjectName, testSecondValue), cta::exception::Exception);
-    // Check the creation of the obecjt
-    bvfs.create(testObjectName, testValue);
-    // Check we can validate the presence of the object
-    ASSERT_EQ(true, bvfs.exists(testObjectName));
-    // Check that we can read back after creation
-    ASSERT_EQ(testValue, bvfs.read(testObjectName));
-    bvfs.atomicOverwrite(testObjectName, testSecondValue);
-    // Check that an update goes through
-    ASSERT_EQ(testSecondValue, bvfs.read(testObjectName));
-    // Check that we read back the value
-    ASSERT_EQ(testSecondValue, bvfs.read(testObjectName));
-    // Check we can delete the object
-    ASSERT_NO_THROW(bvfs.remove(testObjectName));
-    // Check that the object is actually gone
-    ASSERT_EQ(false, bvfs.exists(testObjectName));
-  }
-}
\ No newline at end of file
diff --git a/objectstore/CMakeLists.txt b/objectstore/CMakeLists.txt
index ea65f7cb75..347346a6a8 100644
--- a/objectstore/CMakeLists.txt
+++ b/objectstore/CMakeLists.txt
@@ -12,9 +12,9 @@ PROTOBUF_GENERATE_CPP(CTAProtoSources CTAProtoHeaders ${CTAProtoFiles})
 
 add_library (CTAObjectStore 
   ${CTAProtoSources}
-#  RootEntry.cpp
-#  Agent.cpp
-#  AgentRegister.cpp
+  RootEntry.cpp
+  Agent.cpp
+  AgentRegister.cpp
   BackendVFS.cpp
   BackendRados.cpp
   exception/Backtrace.cpp
@@ -51,9 +51,8 @@ add_library (CTAObjectStore
 #   protobuf rados CTAObjectStore)
 
 set(ObjectStoreUnitTests
-  BackendVFSTest.cpp
-  BackendAbstractTests.cpp)
-#  RootEntryTest.cpp)
+  BackendTest.cpp
+  RootEntryTest.cpp)
 
 add_executable(unitTests unitTests.cpp ${ObjectStoreUnitTests})
 target_link_libraries(unitTests
diff --git a/objectstore/ObjectOps.hpp b/objectstore/ObjectOps.hpp
index fe21f96069..4b07a54cc4 100644
--- a/objectstore/ObjectOps.hpp
+++ b/objectstore/ObjectOps.hpp
@@ -1,38 +1,46 @@
 #pragma once
 
 #include "Backend.hpp"
+#include "exception/Exception.hpp"
+#include <memory>
 
 namespace cta { namespace objectstore {
 
 template <class C>
 class ObjectOps {
 public:
-  ObjectOps(ObjectStore & os, const std::string & name):m_nameSet(true), m_name(name),
+  ObjectOps(Backend & os, const std::string & name):m_nameSet(true), m_name(name),
     m_objectStore(os) {}
   
-  ObjectOps(ObjectStore & os): m_nameSet(false), m_objectStore(os) {}
+  ObjectOps(Backend & os): m_nameSet(false), m_objectStore(os) {}
   
   class NameNotSet: public cta::exception::Exception {
   public:
     NameNotSet(const std::string & w): cta::exception::Exception(w) {}
   };
   
+  class AlreadyLocked: public cta::exception::Exception {
+  public:
+    AlreadyLocked(const std::string & w): cta::exception::Exception(w) {}
+  };
+  
   void setName(const std::string & name) {
     m_name = name;
     m_nameSet = true;
   }
   
-  void updateFromObjectStore (C & val, ContextHandle & context) {
+  void updateFromObjectStore (C & val) {
     if(!m_nameSet) throw NameNotSet("In ObjectOps<>::updateFromObjectStore: name not set");
-    m_objectStore.lockShared(m_name, context);
+    std::auto_ptr<Backend::ScopedLock> lock (m_objectStore.lockShared(m_name));
     std::string reStr = m_objectStore.read(m_name);
-    m_objectStore.unlock(m_name, context);
+    lock->release();
     val.ParseFromString(reStr);
   }
   
-  void lockExclusiveAndRead (C & val, ContextHandle & context, std::string where) {
+  void lockExclusiveAndRead (C & val) {
     if(!m_nameSet) throw NameNotSet("In ObjectOps<>::updateFromObjectStore: name not set");
-    m_objectStore.lockExclusive(m_name, context, where);
+    if(NULL != m_writeLock.get()) throw AlreadyLocked("In ObjectOps<>::updateFromObjectStore: already lcoked for write");
+    m_writeLock.reset(m_objectStore.lockExclusive(m_name));
     // Re-read to get latest version (lock upgrade could be useful here)
     std::string reStr = m_objectStore.read(m_name);
     if (reStr.size())
@@ -44,10 +52,10 @@ public:
     m_objectStore.atomicOverwrite(m_name, val.SerializeAsString());
   }
   
-  void unlock (ContextHandle & context, std::string where="") {
+  void unlock () {
     if(!m_nameSet) throw NameNotSet("In ObjectOps<>::updateFromObjectStore: name not set");
     // release the lock, and return the register name
-    m_objectStore.unlock(m_name, context, where);
+    m_writeLock.reset(NULL);
   }
   
   void remove () {
@@ -70,14 +78,15 @@ public:
     return m_name;
   }
   
-  ObjectStore & objectStore() {
+  Backend & objectStore() {
     return m_objectStore;
   }
   
 private:
   bool m_nameSet;
   std::string m_name;
-  ObjectStore & m_objectStore;
+  Backend & m_objectStore;
+  std::auto_ptr<Backend::ScopedLock> m_writeLock;  
 };
 
 }}
\ No newline at end of file
diff --git a/objectstore/ObjectStoreChoice.hpp b/objectstore/ObjectStoreChoice.hpp
deleted file mode 100644
index c87d6d3dc0..0000000000
--- a/objectstore/ObjectStoreChoice.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "ObjectOps.hpp"
-#define USE_RADOS 1
-#if USE_RADOS
-typedef cta::objectstore::BackendRados myOS;
-#else
-typedef cta::objectstore::BackendVFS myOS;
-#endif
\ No newline at end of file
diff --git a/objectstore/RootEntry.cpp b/objectstore/RootEntry.cpp
index 7bff1b8980..1dcccfbcf9 100644
--- a/objectstore/RootEntry.cpp
+++ b/objectstore/RootEntry.cpp
@@ -20,14 +20,14 @@ cta::objectstore::RootEntry::RootEntry(Agent & agent):
   ObjectOps<serializers::RootEntry>(agent.objectStore(), s_rootEntryName) {
   // Check that the root entry is readable.
   serializers::RootEntry res;
-  updateFromObjectStore(res, agent.getFreeContext());
+  updateFromObjectStore(res);
 }
 
 // Get the name of the agent register (or exception if not available)
 std::string cta::objectstore::RootEntry::getAgentRegister(Agent & agent) {
   // Check if the agent register exists
   serializers::RootEntry res;
-  updateFromObjectStore(res, agent.getFreeContext());
+  updateFromObjectStore(res);
   // If the registry is defined, return it, job done.
   if (res.agentregister().size())
     return res.agentregister();
@@ -43,11 +43,10 @@ std::string cta::objectstore::RootEntry::allocateOrGetAgentRegister(Agent & agen
     // If we get here, the agent register is not created yet, so we have to do it:
     // lock the entry again, for writing
     serializers::RootEntry res;
-    ContextHandle & context = agent.getFreeContext();
-    lockExclusiveAndRead(res, context, "RootEntry::allocateOrGetAgentRegister");
+    lockExclusiveAndRead(res);
     // If the registry is already defined, somebody was faster. We're done.
     if (res.agentregister().size()) {
-      unlock(context);
+      unlock();
       return res.agentregister();
     }
     // We will really create the register
@@ -67,7 +66,7 @@ std::string cta::objectstore::RootEntry::allocateOrGetAgentRegister(Agent & agen
     res.mutable_agentregisterintentlog()->RemoveLast();
     write(res);
     // release the lock, and return the register name
-    unlock(context);
+    unlock();
     return arName;
   }
 }
@@ -76,7 +75,7 @@ std::string cta::objectstore::RootEntry::allocateOrGetAgentRegister(Agent & agen
 std::string cta::objectstore::RootEntry::getJobPool(Agent & agent) {
   // Check if the job pool exists
   serializers::RootEntry res;
-  updateFromObjectStore(res, agent.getFreeContext());
+  updateFromObjectStore(res);
   // If the registry is defined, return it, job done.
   if (res.jobpool().size())
     return res.jobpool();
@@ -92,18 +91,17 @@ std::string cta::objectstore::RootEntry::allocateOrGetJobPool(Agent & agent) {
     // If we get here, the job pool is not created yet, so we have to do it:
     // lock the entry again, for writing
     serializers::RootEntry res;
-    ContextHandle & context = agent.getFreeContext();
-    lockExclusiveAndRead(res, context, "RootEntry::allocateOrGetJobPool");
+    lockExclusiveAndRead(res);
     // If the registry is already defined, somebody was faster. We're done.
     if (res.jobpool().size()) {
-      unlock(context);
+      unlock();
       return res.jobpool();
     }
     // We will really create the register
     // decide on the object's name
     std::string jpName (agent.nextId("jobPool"));
     // Record the agent in the intent log
-    agent.addToIntend(s_rootEntryName, jpName, serializers::JobPool_t);
+    agent.addToOwnership(jpName);
     // The potential object can now be garbage collected if we die from here.
     // Create the object, then lock. The name should be unique, so no race.
     serializers::JobPool jps;
@@ -116,9 +114,9 @@ std::string cta::objectstore::RootEntry::allocateOrGetJobPool(Agent & agent) {
     res.set_jobpool(jpName);
     write(res);
     // release the lock, and return the register name
-    unlock(context);
+    unlock();
     // Clear intent log
-    agent.removeFromIntent(s_rootEntryName, jpName, serializers::JobPool_t);
+    agent.removeFromOwnership(jpName);
     return jpName;
   }
 }
@@ -127,7 +125,7 @@ std::string cta::objectstore::RootEntry::allocateOrGetJobPool(Agent & agent) {
 std::string cta::objectstore::RootEntry::dump (Agent & agent) {
   std::stringstream ret;
   serializers::RootEntry res;
-  updateFromObjectStore(res, agent.getFreeContext());
+  updateFromObjectStore(res);
   ret << "<<<< Root entry dump start" << std::endl;
   if (res.has_agentregister()) ret << "agentRegister=" << res.agentregister() << std::endl;
   ret << "agentRegister Intent Log size=" << res.agentregisterintentlog_size() << std::endl;
diff --git a/objectstore/RootEntryTest.cpp b/objectstore/RootEntryTest.cpp
index 49c16246d6..e054a233a7 100644
--- a/objectstore/RootEntryTest.cpp
+++ b/objectstore/RootEntryTest.cpp
@@ -4,5 +4,9 @@
 #include "RootEntry.hpp"
 
 TEST(RootEntry, BasicAccess) {
-  
-};
\ No newline at end of file
+  cta::objectstore::BackendVFS be;
+  // Try to create the root entry
+  cta::objectstore::RootEntry::init(be);
+  // Delete the root entry
+  be.remove("root");
+}
\ No newline at end of file
-- 
GitLab