From 560f2eb2494129c755d73eec129aeda4c4414511 Mon Sep 17 00:00:00 2001
From: Michael Davis <michael.davis@cern.ch>
Date: Fri, 21 Jun 2019 16:00:05 +0200
Subject: [PATCH] [cta-admin] Converts integer types into enums in "cta-admin
 drive ls"

This allows JSON display of text labels for mount type, drive state
and drive status.
---
 cmdline/CtaAdminTextFormatter.cpp             | 26 +++----
 common/dataStructures/DriveStatusSerDeser.hpp | 68 +++++++++++++++++++
 common/dataStructures/MountType.hpp           |  1 +
 common/dataStructures/MountTypeSerDeser.hpp   | 57 ++++++++++++++++
 xroot_plugins/XrdCtaDriveLs.hpp               |  7 +-
 xrootd-ssi-protobuf-interface                 |  2 +-
 6 files changed, 142 insertions(+), 19 deletions(-)
 create mode 100644 common/dataStructures/DriveStatusSerDeser.hpp
 create mode 100644 common/dataStructures/MountTypeSerDeser.hpp

diff --git a/cmdline/CtaAdminTextFormatter.cpp b/cmdline/CtaAdminTextFormatter.cpp
index 311c210c07..7aa306b75f 100644
--- a/cmdline/CtaAdminTextFormatter.cpp
+++ b/cmdline/CtaAdminTextFormatter.cpp
@@ -20,8 +20,8 @@
 #include <iostream>
 #include <iomanip>
 #include <cmdline/CtaAdminTextFormatter.hpp>
-#include <common/dataStructures/DriveStatus.hpp>
-#include <common/dataStructures/MountType.hpp>
+#include <common/dataStructures/DriveStatusSerDeser.hpp>
+#include <common/dataStructures/MountTypeSerDeser.hpp>
 
 namespace cta {
 namespace admin {
@@ -257,12 +257,10 @@ void TextFormatter::printDriveLsHeader() {
 
 void TextFormatter::print(const DriveLsItem &drls_item)
 {
-  using namespace cta::common::dataStructures;
+  //using namespace cta::common::dataStructures;
 
   const int DRIVE_TIMEOUT = 600; // Time after which a drive will be marked as STALE
 
-  std::string mountType;
-  std::string driveStatus;
   std::string driveStatusSince;
   std::string filesTransferredInSession;
   std::string bytesTransferredInSession;
@@ -270,22 +268,20 @@ void TextFormatter::print(const DriveLsItem &drls_item)
   std::string sessionId;
   std::string timeSinceLastUpdate;
 
-  mountType   = toString(static_cast<MountType>(drls_item.mount_type()));
-  driveStatus = toString(static_cast<DriveStatus>(drls_item.drive_status()));
 
-  if(drls_item.drive_status() != DriveStatus::Unknown) {
+  if(drls_item.drive_status() != DriveLsItem::UNKNOWN_DRIVE_STATUS) {
     driveStatusSince = std::to_string(drls_item.drive_status_since());
   }
 
-  if(drls_item.drive_status() == DriveStatus::Transferring) {
+  if(drls_item.drive_status() == DriveLsItem::TRANSFERRING) {
     filesTransferredInSession = std::to_string(drls_item.files_transferred_in_session());
     bytesTransferredInSession = dataSizeToStr(drls_item.bytes_transferred_in_session());
     latestBandwidth = std::to_string(drls_item.latest_bandwidth());
   }
 
-  if(drls_item.drive_status() != DriveStatus::Up &&
-     drls_item.drive_status() != DriveStatus::Down &&
-     drls_item.drive_status() != DriveStatus::Unknown) {
+  if(drls_item.drive_status() != DriveLsItem::UP &&
+     drls_item.drive_status() != DriveLsItem::DOWN &&
+     drls_item.drive_status() != DriveLsItem::UNKNOWN_DRIVE_STATUS) {
     sessionId = std::to_string(drls_item.session_id());
   }
 
@@ -296,9 +292,9 @@ void TextFormatter::print(const DriveLsItem &drls_item)
     drls_item.logical_library(),
     drls_item.drive_name(),
     drls_item.host(),
-    drls_item.desired_drive_state() == DriveLsItem::UP ? "Up" : "Down",
-    mountType,
-    driveStatus,
+    (drls_item.desired_drive_state() == DriveLsItem::UP ? "Up" : "Down"),
+    toString(ProtobufToMountType(drls_item.mount_type())),
+    toString(ProtobufToDriveStatus(drls_item.drive_status())),
     driveStatusSince,
     drls_item.vid(),
     drls_item.tapepool(),
diff --git a/common/dataStructures/DriveStatusSerDeser.hpp b/common/dataStructures/DriveStatusSerDeser.hpp
new file mode 100644
index 0000000000..d6d4be35e9
--- /dev/null
+++ b/common/dataStructures/DriveStatusSerDeser.hpp
@@ -0,0 +1,68 @@
+/*!
+ * @project        The CERN Tape Archive (CTA)
+ * @brief          Convert common::dataStructures::DriveStatus to/from admin::DriveLsItem::DriveStatus
+ * @copyright      Copyright 2019 CERN
+ * @license        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/>.
+ */
+
+#pragma once
+
+#include <common/dataStructures/DriveStatus.hpp>
+#include "cta_admin.pb.h"
+
+namespace cta {
+namespace admin {
+
+common::dataStructures::DriveStatus ProtobufToDriveStatus(DriveLsItem::DriveStatus driveStatus) {
+  using namespace common::dataStructures;
+
+  switch(driveStatus) {
+    case DriveLsItem::DOWN:                    return DriveStatus::Down;
+    case DriveLsItem::UP:                      return DriveStatus::Up;
+    case DriveLsItem::PROBING:                 return DriveStatus::Probing;
+    case DriveLsItem::STARTING:                return DriveStatus::Starting;
+    case DriveLsItem::MOUNTING:                return DriveStatus::Mounting;
+    case DriveLsItem::TRANSFERRING:            return DriveStatus::Transferring;
+    case DriveLsItem::UNLOADING:               return DriveStatus::Unloading;
+    case DriveLsItem::UNMOUNTING:              return DriveStatus::Unmounting;
+    case DriveLsItem::DRAINING_TO_DISK:        return DriveStatus::DrainingToDisk;
+    case DriveLsItem::CLEANING_UP:             return DriveStatus::CleaningUp;
+    case DriveLsItem::SHUTDOWN:                return DriveStatus::Shutdown;
+    case DriveLsItem::UNKNOWN_DRIVE_STATUS:
+    default:
+                                               return DriveStatus::Unknown;
+  }
+}
+
+DriveLsItem::DriveStatus DriveStatusToProtobuf(common::dataStructures::DriveStatus driveStatus) {
+  using namespace common::dataStructures;
+
+  switch(driveStatus) {
+    case DriveStatus::Down:                    return DriveLsItem::DOWN;
+    case DriveStatus::Up:                      return DriveLsItem::UP;
+    case DriveStatus::Probing:                 return DriveLsItem::PROBING;
+    case DriveStatus::Starting:                return DriveLsItem::STARTING;
+    case DriveStatus::Mounting:                return DriveLsItem::MOUNTING;
+    case DriveStatus::Transferring:            return DriveLsItem::TRANSFERRING;
+    case DriveStatus::Unloading:               return DriveLsItem::UNLOADING;
+    case DriveStatus::Unmounting:              return DriveLsItem::UNMOUNTING;
+    case DriveStatus::DrainingToDisk:          return DriveLsItem::DRAINING_TO_DISK;
+    case DriveStatus::CleaningUp:              return DriveLsItem::CLEANING_UP;
+    case DriveStatus::Shutdown:                return DriveLsItem::SHUTDOWN;
+    case DriveStatus::Unknown:                 return DriveLsItem::UNKNOWN_DRIVE_STATUS;
+  }
+  return DriveLsItem::UNKNOWN_DRIVE_STATUS;
+}
+
+}} // cta::admin
diff --git a/common/dataStructures/MountType.hpp b/common/dataStructures/MountType.hpp
index 520023b242..b10bc44baa 100644
--- a/common/dataStructures/MountType.hpp
+++ b/common/dataStructures/MountType.hpp
@@ -23,6 +23,7 @@
 namespace cta {
 namespace common {
 namespace dataStructures {
+
 enum class MountType: uint32_t {
   ArchiveForUser = 1,
   ArchiveForRepack = 2,
diff --git a/common/dataStructures/MountTypeSerDeser.hpp b/common/dataStructures/MountTypeSerDeser.hpp
new file mode 100644
index 0000000000..3774d324d6
--- /dev/null
+++ b/common/dataStructures/MountTypeSerDeser.hpp
@@ -0,0 +1,57 @@
+/*!
+ * @project        The CERN Tape Archive (CTA)
+ * @brief          Convert common::dataStructures::MountType to/from admin::DriveLsItem::MountType
+ * @copyright      Copyright 2019 CERN
+ * @license        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/>.
+ */
+
+#pragma once
+
+#include <common/dataStructures/MountType.hpp>
+#include "cta_admin.pb.h"
+
+namespace cta {
+namespace admin {
+
+common::dataStructures::MountType ProtobufToMountType(DriveLsItem::MountType mountType) {
+  using namespace common::dataStructures;
+
+  switch(mountType) {
+    case DriveLsItem::NO_MOUNT:              return MountType::NoMount;
+    case DriveLsItem::ARCHIVE_FOR_USER:      return MountType::ArchiveForUser;
+    case DriveLsItem::ARCHIVE_FOR_REPACK:    return MountType::ArchiveForRepack;
+    case DriveLsItem::ARCHIVE_ALL_TYPES:     return MountType::ArchiveAllTypes;
+    case DriveLsItem::RETRIEVE:              return MountType::Retrieve;
+    case DriveLsItem::LABEL:                 return MountType::Label;
+    case DriveLsItem::UNKNOWN_MOUNT_TYPE:
+    default:
+      throw std::runtime_error("In ProtobufToMountType(): unknown mount type " + std::to_string(mountType));
+  }
+}
+
+DriveLsItem::MountType MountTypeToProtobuf(common::dataStructures::MountType mountType) {
+  using namespace common::dataStructures;
+
+  switch(mountType) {
+    case MountType::NoMount:                 return DriveLsItem::NO_MOUNT;
+    case MountType::ArchiveForUser:          return DriveLsItem::ARCHIVE_FOR_USER;
+    case MountType::ArchiveForRepack:        return DriveLsItem::ARCHIVE_FOR_REPACK;
+    case MountType::ArchiveAllTypes:         return DriveLsItem::ARCHIVE_ALL_TYPES;
+    case MountType::Retrieve:                return DriveLsItem::RETRIEVE;
+    case MountType::Label:                   return DriveLsItem::LABEL;
+  }
+  return DriveLsItem::UNKNOWN_MOUNT_TYPE;
+}
+
+}} // cta::admin
diff --git a/xroot_plugins/XrdCtaDriveLs.hpp b/xroot_plugins/XrdCtaDriveLs.hpp
index d62385e773..7d1df9bf5a 100644
--- a/xroot_plugins/XrdCtaDriveLs.hpp
+++ b/xroot_plugins/XrdCtaDriveLs.hpp
@@ -20,7 +20,8 @@
 
 #include <xroot_plugins/XrdCtaStream.hpp>
 #include <xroot_plugins/XrdSsiCtaRequestMessage.hpp>
-
+#include <common/dataStructures/DriveStatusSerDeser.hpp>
+#include <common/dataStructures/MountTypeSerDeser.hpp>
 
 namespace cta { namespace xrd {
 
@@ -109,8 +110,8 @@ int DriveLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) {
     dr_item->set_drive_name(dr.driveName);
     dr_item->set_host(dr.host);
     dr_item->set_desired_drive_state(dr.desiredDriveState.up ? DriveLsItem::UP : DriveLsItem::DOWN);
-    dr_item->set_mount_type(static_cast<uint32_t>(dr.mountType));
-    dr_item->set_drive_status(dr.driveStatus);
+    dr_item->set_mount_type(MountTypeToProtobuf(dr.mountType));
+    dr_item->set_drive_status(DriveStatusToProtobuf(dr.driveStatus));
     dr_item->set_vid(dr.currentVid);
     dr_item->set_tapepool(dr.currentTapePool);
     dr_item->set_files_transferred_in_session(dr.filesTransferredInSession);
diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface
index 86937b02d8..7c6e0d5e1b 160000
--- a/xrootd-ssi-protobuf-interface
+++ b/xrootd-ssi-protobuf-interface
@@ -1 +1 @@
-Subproject commit 86937b02d89bdce5bffe792865257ae66b8f9374
+Subproject commit 7c6e0d5e1b666e34212847d96c5ca52e9af3fc7c
-- 
GitLab