From cb013de2d01117d621f978fb8c179d80df49cc4c Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Wed, 28 Jun 2017 17:35:56 +0200
Subject: [PATCH] Created an objectstore utility for requeuing ArchiveRequests
 after deleting archive or retrieve queues.

This utility is to be used for cleaning up the pre-prod environement following a schema change in the archive queues.
It could support all object types on the long run, but currently only supports ArchiveRequests.
---
 cta.spec.in                                   |  1 +
 objectstore/CMakeLists.txt                    |  5 +
 ...ta-objectstore-collect-orphaned-object.cpp | 97 +++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 objectstore/cta-objectstore-collect-orphaned-object.cpp

diff --git a/cta.spec.in b/cta.spec.in
index 5205d47077..c996c464c4 100644
--- a/cta.spec.in
+++ b/cta.spec.in
@@ -247,6 +247,7 @@ Tools allowing initialization and inspection of the object store.
 %attr(0755,root,root) %{_bindir}/cta-objectstore-dump-object
 %attr(0755,root,root) %{_bindir}/cta-objectstore-unfollow-agent
 %attr(0755,root,root) %{_bindir}/cta-objectstore-dereference-removed-queues
+%attr(0755,root,root) %{_bindir}/cta-objectstore-collect-orphaned-object
 
 #cta-systemtests installs libraries so we need ldconfig.
 %post -n cta-systemtests -p /sbin/ldconfig
diff --git a/objectstore/CMakeLists.txt b/objectstore/CMakeLists.txt
index d240ae4679..1f01662a80 100644
--- a/objectstore/CMakeLists.txt
+++ b/objectstore/CMakeLists.txt
@@ -111,6 +111,11 @@ set_target_properties(cta-objectstore-dereference-removed-queues PROPERTIES INST
 target_link_libraries(cta-objectstore-dereference-removed-queues
   ${PROTOBUF3_LIBRARIES} ctaobjectstore ctacommon)
 
+add_executable(cta-objectstore-collect-orphaned-object cta-objectstore-collect-orphaned-object.cpp)
+set_target_properties(cta-objectstore-collect-orphaned-object PROPERTIES INSTALL_RPATH ${PROTOBUF3_RPATH})
+target_link_libraries(cta-objectstore-collect-orphaned-object
+  ${PROTOBUF3_LIBRARIES} ctaobjectstore ctacommon)
+
 install(TARGETS cta-objectstore-initialize cta-objectstore-list cta-objectstore-dump-object cta-objectstore-unfollow-agent 
   cta-objectstore-dereference-removed-queues
   DESTINATION usr/bin)
diff --git a/objectstore/cta-objectstore-collect-orphaned-object.cpp b/objectstore/cta-objectstore-collect-orphaned-object.cpp
new file mode 100644
index 0000000000..ed95792a15
--- /dev/null
+++ b/objectstore/cta-objectstore-collect-orphaned-object.cpp
@@ -0,0 +1,97 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * This program takes the address of an object as second parameter. If the object is orphaned,
+ * it will be garbage collected.
+ */
+
+#include "BackendFactory.hpp"
+#include "BackendVFS.hpp"
+#include "AgentReference.hpp"
+#include "Agent.hpp"
+#include "RootEntry.hpp"
+#include "ArchiveRequest.hpp"
+#include "GenericObject.hpp"
+#include <iostream>
+#include <stdexcept>
+
+int main(int argc, char ** argv) {
+  try {
+    std::unique_ptr<cta::objectstore::Backend> be;
+    if (3 == argc) {
+      be.reset(cta::objectstore::BackendFactory::createBackend(argv[1]).release());
+    } else {
+      throw std::runtime_error("Wrong number of arguments: expected 2");
+    }
+    // If the backend is a VFS, make sure we don't delete it on exit.
+    // If not, nevermind.
+    try {
+      dynamic_cast<cta::objectstore::BackendVFS &>(*be).noDeleteOnExit();
+    } catch (std::bad_cast &){}
+    std::cout << "Object store path: " << be->getParams()->toURL() << std::endl;
+    // Try and open the object.
+    cta::objectstore::GenericObject go(argv[2], *be);
+    cta::objectstore::ScopedExclusiveLock gol(go);
+    std::cout << "Object address: " << go.getAddressIfSet() << std::endl;
+    go.fetch();
+    // Create an AgentReference in case we need it
+    cta::objectstore::AgentReference agr("cta-objectstore-collect-orphaned-object");
+    cta::objectstore::Agent ag(agr.getAgentAddress(), *be);
+    ag.initialize();
+    ag.insertAndRegisterSelf();
+    switch (go.type()) {
+    case cta::objectstore::serializers::ObjectType::ArchiveRequest_t:
+    {
+      // Reopen the object as an ArchiveRequest
+      std::cout << "The object is an ArchiveRequest" << std::endl;
+      gol.release();
+      bool someGcDone=false;
+    gcpass:
+      cta::objectstore::ArchiveRequest ar(argv[2], *be);
+      cta::objectstore::ScopedExclusiveLock arl(ar);
+      ar.fetch();
+      for (auto & j: ar.dumpJobs()) {
+        if (!be->exists(j.owner)) {
+          std::cout << "Owner " << j.owner << " for job " <<  j.copyNb << " does not exist." << std::endl;
+          ar.garbageCollect(j.owner, agr);
+          someGcDone=true;
+          goto gcpass;
+        }
+      }
+      if (someGcDone) {
+        ar.fetch();
+        for (auto & j: ar.dumpJobs()) {
+          std::cout << "New owner for job " << j.copyNb << " is " << j.owner << std::endl;
+        }
+      } else {
+        std::cout << "No job was orphaned." << std::endl;
+      }
+      break;
+    }
+    default:
+      std::cout << "Object type: " << go.type() << " not supported for this operation" << std::endl;
+      break;
+    }
+    cta::objectstore::ScopedExclusiveLock agl(ag);
+    ag.removeAndUnregisterSelf();
+  } catch (std::exception & e) {
+    std::cerr << "Failed to garbage collect object: "
+        << std::endl << e.what() << std::endl;
+  }
+}
\ No newline at end of file
-- 
GitLab