]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
d4n/directory: Add `ObjectDirectory::update_field` method
authorSamarah <samarah.uriarte@ibm.com>
Thu, 9 Nov 2023 14:28:07 +0000 (14:28 +0000)
committerPritha Srivastava <prsrivas@redhat.com>
Tue, 2 Apr 2024 15:54:51 +0000 (21:24 +0530)
Signed-off-by: Samarah <samarah.uriarte@ibm.com>
src/rgw/driver/d4n/d4n_directory.cc
src/rgw/driver/d4n/d4n_directory.h
src/test/rgw/test_d4n_directory.cc

index a518417e19b24054ac89a69696af4a7c79cac096..b0971349698d07cee17b838811ecda3f3d970204 100644 (file)
@@ -74,8 +74,8 @@ void ObjectDirectory::shutdown()
 int ObjectDirectory::set(CacheObj* object, optional_yield y) {
   std::string key = build_index(object);
     
-  /* Every set will be treated as new */ // or maybe, if key exists, simply return? -Sam
-  std::string endpoint = cct->_conf->rgw_d4n_host + ":" + std::to_string(cct->_conf->rgw_d4n_port);
+  /* Every set will be treated as new */
+  std::string endpoint;
   std::list<std::string> redisValues;
     
   /* Creating a redisValues of the entry's properties */
@@ -88,6 +88,17 @@ int ObjectDirectory::set(CacheObj* object, optional_yield y) {
   redisValues.push_back("dirty");
   redisValues.push_back(std::to_string(object->dirty));
   redisValues.push_back("objHosts");
+
+  for (auto const& host : object->hostsList) {
+    if (endpoint.empty())
+      endpoint = host + "_";
+    else
+      endpoint = endpoint + host + "_";
+  }
+
+  if (!endpoint.empty())
+    endpoint.pop_back();
+
   redisValues.push_back(endpoint); 
 
   try {
@@ -223,6 +234,63 @@ int ObjectDirectory::del(CacheObj* object, optional_yield y) {
   }
 }
 
+int ObjectDirectory::update_field(CacheObj* object, std::string field, std::string value, optional_yield y) {
+  std::string key = build_index(object);
+
+  if (exist_key(object, y)) {
+    try {
+      /* Ensure field exists */
+      {
+       boost::system::error_code ec;
+       request req;
+       req.push("HEXISTS", key, field);
+       response<int> resp;
+
+       redis_exec(conn, ec, req, resp, y);
+
+       if (!std::get<0>(resp).value() || (bool)ec)
+         return -1;
+      }
+
+      if (field == "objHosts") {
+       /* Append rather than overwrite */
+       boost::system::error_code ec;
+       request req;
+       req.push("HGET", key, field);
+       response<std::string> resp;
+
+       redis_exec(conn, ec, req, resp, y);
+
+       if (!std::get<0>(resp).value().size() || (bool)ec)
+         return -1;
+
+       std::get<0>(resp).value() += "_";
+       std::get<0>(resp).value() += value;
+       value = std::get<0>(resp).value();
+      }
+
+      {
+       boost::system::error_code ec;
+       request req;
+       req.push_range("HSET", key, std::map<std::string, std::string>{{field, value}});
+       response<int> resp;
+
+       redis_exec(conn, ec, req, resp, y);
+
+       if ((bool)ec) {
+         return -1;
+       }
+
+       return std::get<0>(resp).value(); 
+      }
+    } catch(std::exception &e) {
+      return -1;
+    }
+  } else {
+    return -2;
+  }
+}
+
 std::string BlockDirectory::build_index(CacheBlock* block) {
   return block->cacheObj.bucketName + "_" + block->cacheObj.objName + "_" + std::to_string(block->blockID) + "_" + std::to_string(block->size);
 }
@@ -276,7 +344,9 @@ int BlockDirectory::set(CacheBlock* block, optional_yield y) {
       endpoint = endpoint + host + "_";
   }
 
-  endpoint.pop_back();
+  if (!endpoint.empty())
+    endpoint.pop_back();
+
   redisValues.push_back(endpoint);
 
   redisValues.push_back("objName");
@@ -297,7 +367,9 @@ int BlockDirectory::set(CacheBlock* block, optional_yield y) {
       endpoint = endpoint + host + "_";
   }
 
-  endpoint.pop_back();
+  if (!endpoint.empty())
+    endpoint.pop_back();
+
   redisValues.push_back(endpoint);
 
   try {
@@ -474,7 +546,7 @@ int BlockDirectory::update_field(CacheBlock* block, std::string field, std::stri
          return -1;
       }
 
-      if (field == "blockHosts") { // Need one for object hosts? -Sam
+      if (field == "blockHosts") { 
        /* Append rather than overwrite */
        boost::system::error_code ec;
        request req;
@@ -503,7 +575,7 @@ int BlockDirectory::update_field(CacheBlock* block, std::string field, std::stri
          return -1;
        }
 
-       return std::get<0>(resp).value(); /* Zero fields added since it is an update of an existing field */ 
+       return std::get<0>(resp).value(); 
       }
     } catch(std::exception &e) {
       return -1;
index 5e6c620730fd9a3be32a2b0f56de650f57d131d6..b98859d70dbe9c9b126912adc67b305b18b3cf4d 100644 (file)
@@ -40,7 +40,7 @@ class Directory {
     Directory() {}
 };
 
-class ObjectDirectory: public Directory { // weave into write workflow -Sam
+class ObjectDirectory: public Directory {
   public:
     ObjectDirectory(net::io_context& io_context) {
       conn = std::make_shared<connection>(boost::asio::make_strand(io_context));
@@ -53,7 +53,7 @@ class ObjectDirectory: public Directory { // weave into write workflow -Sam
       this->cct = cct;
 
       config cfg;
-      cfg.addr.host = cct->_conf->rgw_d4n_host; // same or different address from block directory? -Sam
+      cfg.addr.host = cct->_conf->rgw_d4n_host;
       cfg.addr.port = std::to_string(cct->_conf->rgw_d4n_port);
       cfg.clientname = "D4N.ObjectDir";
 
@@ -73,6 +73,7 @@ class ObjectDirectory: public Directory { // weave into write workflow -Sam
     int get(CacheObj* object, optional_yield y);
     int copy(CacheObj* object, std::string copyName, std::string copyBucketName, optional_yield y);
     int del(CacheObj* object, optional_yield y);
+    int update_field(CacheObj* object, std::string field, std::string value, optional_yield y);
 
   private:
     std::shared_ptr<connection> conn;
index 4ce35eaf1d2f5d1cbd176dc635b6e6b8741b11e3..dfb01de2e9461ca91f55550fe56937eadce4190f 100644 (file)
@@ -271,6 +271,34 @@ TEST_F(ObjectDirectoryFixture, DelYield)
   io.run();
 }
 
+TEST_F(ObjectDirectoryFixture, UpdateFieldYield)
+{
+  spawn::spawn(io, [this] (spawn::yield_context yield) {
+    ASSERT_EQ(0, dir->set(obj, optional_yield{io, yield}));
+    ASSERT_EQ(0, dir->update_field(obj, "objName", "newTestName", optional_yield{io, yield}));
+    ASSERT_EQ(0, dir->update_field(obj, "objHosts", "127.0.0.1:5000", optional_yield{io, yield}));
+    dir->shutdown();
+
+    boost::system::error_code ec;
+    request req;
+    req.push("HMGET", "testBucket_testName", "objName", "objHosts");
+    req.push("FLUSHALL");
+    response< std::vector<std::string>, 
+             boost::redis::ignore_t> resp;
+
+    conn->async_exec(req, resp, yield[ec]);
+
+    ASSERT_EQ((bool)ec, false);
+    EXPECT_EQ(std::get<0>(resp).value()[0], "newTestName");
+    EXPECT_EQ(std::get<0>(resp).value()[1], "127.0.0.1:6379_127.0.0.1:5000");
+
+    conn->cancel();
+  });
+
+  io.run();
+}
+
+
 TEST_F(BlockDirectoryFixture, SetYield)
 {
   spawn::spawn(io, [this] (spawn::yield_context yield) {