From a647843f4ff48a530ebecbf46faad1c727f78796 Mon Sep 17 00:00:00 2001
From: Michael Davis <michael.davis@cern.ch>
Date: Wed, 20 Sep 2017 15:04:32 +0200
Subject: [PATCH] [cta_frontend] Adds setDriveState()

Implements cta_admin drive up|down
---
 xroot_plugins/XrdSsiCtaRequestMessage.cpp | 86 +++++++++++++++--------
 xroot_plugins/XrdSsiCtaRequestMessage.hpp | 56 +++++++++------
 2 files changed, 92 insertions(+), 50 deletions(-)

diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
index f81d4d93b1..489e0f5d49 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
@@ -18,6 +18,8 @@
 
 #include <iomanip> // for setw
 
+#include <common/utils/Regex.hpp>
+
 #include <XrdSsiPbException.hpp>
 using XrdSsiPb::PbException;
 
@@ -719,15 +721,9 @@ void RequestMessage::processDrive_Up(const cta::admin::AdminCmd &admincmd, cta::
 {
    using namespace cta::admin;
 
-   std::stringstream cmdlineOutput;
-
-#if 0
-   auto &drive = getRequired(OptionString::DRIVE);
-
-   changeStateForDrivesByRegex(drive, m_lc, cmdlineOutput, true, false);
-#endif
+   std::string cmdlineOutput = setDriveState(getRequired(OptionString::DRIVE), Up);
 
-   response.set_message_txt(cmdlineOutput.str());
+   response.set_message_txt(cmdlineOutput);
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
 
@@ -737,15 +733,9 @@ void RequestMessage::processDrive_Down(const cta::admin::AdminCmd &admincmd, cta
 {
    using namespace cta::admin;
 
-   std::stringstream cmdlineOutput;
-
-#if 0
-   auto &drive = getRequired(OptionString::DRIVE);
+   std::string cmdlineOutput = setDriveState(getRequired(OptionString::DRIVE), Down);
 
-   changeStateForDrivesByRegex(drive, m_lc, cmdlineOutput, false, has_flag(OptionBoolean::FORCE));
-#endif
-
-   response.set_message_txt(cmdlineOutput.str());
+   response.set_message_txt(cmdlineOutput);
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
 
@@ -2179,25 +2169,38 @@ void RequestMessage::processVerify_Err(const cta::admin::AdminCmd &admincmd, cta
 
 
 
-void RequestMessage::importOptions(const cta::admin::AdminCmd &admincmd)
+std::string RequestMessage::setDriveState(const std::string &regex, DriveState drive_state)
 {
-   // Validate the Protocol Buffer
-   validateCmd(admincmd);
+   using namespace cta::admin;
 
-   // Import Boolean options
-   for(auto opt_it = admincmd.option_bool().begin(); opt_it != admincmd.option_bool().end(); ++opt_it) {
-      m_option_bool.insert(std::make_pair(opt_it->key(), opt_it->value()));
-   }
+   std::stringstream cmdlineOutput;
 
-   // Import UInt64 options
-   for(auto opt_it = admincmd.option_uint64().begin(); opt_it != admincmd.option_uint64().end(); ++opt_it) {
-      m_option_uint64.insert(std::make_pair(opt_it->key(), opt_it->value()));
-   }
+   cta::utils::Regex driveNameRegex(regex.c_str());
 
-   // Import String options
-   for(auto opt_it = admincmd.option_str().begin(); opt_it != admincmd.option_str().end(); ++opt_it) {
-      m_option_str.insert(std::make_pair(opt_it->key(), opt_it->value()));
+   auto driveStates = m_scheduler.getDriveStates(m_cliIdentity, m_lc);
+   bool is_found = false;
+
+   for(auto driveState: driveStates)
+   {
+      const auto regexResult = driveNameRegex.exec(driveState.driveName);
+      if(!regexResult.empty())
+      {
+         is_found = true;
+
+         m_scheduler.setDesiredDriveState(m_cliIdentity, driveState.driveName, drive_state == Up,
+                                          has_flag(OptionBoolean::FORCE), m_lc);
+
+         cmdlineOutput << "Drive " << driveState.driveName << " set "
+                       << (drive_state == Up ? "Up" : "Down")
+                       << (has_flag(OptionBoolean::FORCE) ? " (forced)" : "")
+                       << "." << std::endl;
+      }
    }
+   if (!is_found) {
+      cmdlineOutput << "Drives not found by regex: " << regex << std::endl;
+   }
+
+   return cmdlineOutput.str();
 }
 
 
@@ -2245,5 +2248,28 @@ void RequestMessage::addLogInfoToResponseRow(std::vector<std::string> &responseR
    responseRow.push_back(timeToString(lastModificationLog.time));
 }
 
+
+
+void RequestMessage::importOptions(const cta::admin::AdminCmd &admincmd)
+{
+   // Validate the Protocol Buffer
+   validateCmd(admincmd);
+
+   // Import Boolean options
+   for(auto opt_it = admincmd.option_bool().begin(); opt_it != admincmd.option_bool().end(); ++opt_it) {
+      m_option_bool.insert(std::make_pair(opt_it->key(), opt_it->value()));
+   }
+
+   // Import UInt64 options
+   for(auto opt_it = admincmd.option_uint64().begin(); opt_it != admincmd.option_uint64().end(); ++opt_it) {
+      m_option_uint64.insert(std::make_pair(opt_it->key(), opt_it->value()));
+   }
+
+   // Import String options
+   for(auto opt_it = admincmd.option_str().begin(); opt_it != admincmd.option_str().end(); ++opt_it) {
+      m_option_str.insert(std::make_pair(opt_it->key(), opt_it->value()));
+   }
+}
+
 }} // namespace cta::xrd
 
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
index 23772e35b4..6e4fb622d5 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
@@ -132,6 +132,41 @@ private:
    admincmd_t processVerify_Ls;
    admincmd_t processVerify_Err;
 
+   /*!
+    * Drive state enum
+    */
+   enum DriveState { Up, Down };
+
+   /*!
+    * Changes state for the drives by a given regex.
+    *
+    * @param[in]     regex          The regex to match drive name(s) to change
+    * @param[in]     drive_state    The desired state for the drives (Up or Down)
+    *
+    * @returns       The result of the operation, to return to the client
+    */
+   std::string setDriveState(const std::string &regex, DriveState drive_state);
+
+   /*!
+    * Returns the response string for admin commands in a tabular format
+    * 
+    * @param[in]     responseTable   The response 2D matrix
+    *
+    * @returns       the response string properly formatted in a table
+    */
+   std::string formatResponse(const std::vector<std::vector<std::string>> &responseTable) const;
+
+   /*!
+    * Adds the creation log and the last modification log to the current response row
+    * 
+    * @param[in,out] responseRow            The current response row to modify
+    * @param[in]     creationLog            the creation log
+    * @param[in]     lastModificationLog    the last modification log
+    */
+   void addLogInfoToResponseRow(std::vector<std::string> &responseRow,
+                                const cta::common::dataStructures::EntryLog &creationLog,
+                                const cta::common::dataStructures::EntryLog &lastModificationLog) const;
+
    /*!
     * Import Google Protobuf option fields into maps
     *
@@ -209,26 +244,6 @@ private:
       return opt_it != m_option_bool.end() && opt_it->second;
    }
 
-   /*!
-    * Returns the response string for admin commands in a tabular format
-    * 
-    * @param[in]     responseTable   The response 2D matrix
-    *
-    * @returns       the response string properly formatted in a table
-    */
-   std::string formatResponse(const std::vector<std::vector<std::string>> &responseTable) const;
-
-   /*!
-    * Adds the creation log and the last modification log to the current response row
-    * 
-    * @param[in,out] responseRow            The current response row to modify
-    * @param[in]     creationLog            the creation log
-    * @param[in]     lastModificationLog    the last modification log
-    */
-   void addLogInfoToResponseRow(std::vector<std::string> &responseRow,
-                                const cta::common::dataStructures::EntryLog &creationLog,
-                                const cta::common::dataStructures::EntryLog &lastModificationLog) const;
-
    // Member variables
 
    cta::catalogue::Catalogue                            &m_catalogue;        //!< Reference to CTA Catalogue
@@ -241,3 +256,4 @@ private:
 };
 
 }} // namespace cta::xrd
+
-- 
GitLab