From ef5aca4a793347738ba3c02ea90eeca15135a895 Mon Sep 17 00:00:00 2001
From: Michael Davis <michael.davis@cern.ch>
Date: Wed, 16 Aug 2017 15:52:52 +0200
Subject: [PATCH] [XrdSsi] Adds skeleton for XrdSsi version of cta admin
 command

---
 cmdline/CMakeLists.txt         |   8 ++
 cmdline/CtaAdminApi.h          |  36 ++++++++
 cmdline/CtaAdminCmdMain.cpp    | 154 +++++++++++++++++++++++++++++++++
 xroot_ssi_pb/XrdSsiPbDebug.hpp |   2 +-
 4 files changed, 199 insertions(+), 1 deletion(-)
 create mode 100644 cmdline/CtaAdminApi.h
 create mode 100644 cmdline/CtaAdminCmdMain.cpp

diff --git a/cmdline/CMakeLists.txt b/cmdline/CMakeLists.txt
index 47f232cb19..54219bb480 100644
--- a/cmdline/CMakeLists.txt
+++ b/cmdline/CMakeLists.txt
@@ -45,3 +45,11 @@ add_executable(eoscta_stub EosCtaStub.cpp)
 target_link_libraries(eoscta_stub cryptopp ctaeosmessages ${PROTOBUF3_LIBRARIES} XrdSsi-4 XrdSsiLib)
 install(TARGETS eoscta_stub DESTINATION usr/bin)
 
+#
+# cta_admin is a drop-in replacement for "cta <admin_command>"
+#
+
+add_executable(cta_admin CtaAdminCmdMain.cpp)
+target_link_libraries(cta_admin ${PROTOBUF3_LIBRARIES} XrdSsi-4 XrdSsiLib)
+install(TARGETS cta_admin DESTINATION usr/bin)
+
diff --git a/cmdline/CtaAdminApi.h b/cmdline/CtaAdminApi.h
new file mode 100644
index 0000000000..6a7a4537a5
--- /dev/null
+++ b/cmdline/CtaAdminApi.h
@@ -0,0 +1,36 @@
+/*!
+ * @project        The CERN Tape Archive (CTA)
+ * @brief          Bind the XRootD SSI transport layer to a set of Google Protocol Buffer definitions
+ * @copyright      Copyright 2017 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/>.
+ */
+
+#ifndef __CTA_ADMIN_API_H
+#define __CTA_ADMIN_API_H
+
+#include "XrdSsiPbServiceClientSide.hpp"     //!< XRootD SSI/Protocol Buffer Service, client-side bindings
+#if 0
+#include "eos/messages/eos_messages.pb.h"    //!< Auto-generated message types from .proto file
+
+/*!
+ * Bind the type of the XrdSsiService to the types defined in the .proto file
+ */
+
+typedef XrdSsiPb::ServiceClientSide<eos::wfe::Notification,    //!< XrdSSi Request message type
+                                    eos::wfe::Response,        //!< XrdSsi Metadata message type
+                                    eos::wfe::Alert>           //!< XrdSsi Alert message type
+        XrdSsiPbServiceType;
+#endif
+
+#endif
diff --git a/cmdline/CtaAdminCmdMain.cpp b/cmdline/CtaAdminCmdMain.cpp
new file mode 100644
index 0000000000..ab735a498c
--- /dev/null
+++ b/cmdline/CtaAdminCmdMain.cpp
@@ -0,0 +1,154 @@
+/*!
+ * @project        The CERN Tape Archive (CTA)
+ * @brief          Command-line tool for CTA Admin commands
+ * @description    CTA Admin command using Google Protocol Buffers and XRootD SSI transport
+ * @copyright      Copyright 2017 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/>.
+ */
+
+#include <stdexcept>
+#include <iostream>
+//#include <sstream>
+
+#include "common/dataStructures/FrontendReturnCode.hpp"
+
+#include "XrdSsiPbDebug.hpp"
+#include "CtaAdminApi.h"
+
+
+
+#if 0
+// Define XRootD SSI Alert message callback
+
+namespace XrdSsiPb {
+
+/*!
+ * Alert callback.
+ *
+ * Defines how Alert messages should be logged by EOS (or directed to the User)
+ */
+
+template<>
+void RequestCallback<eos::wfe::Alert>::operator()(const eos::wfe::Alert &alert)
+{
+   std::cout << "AlertCallback():" << std::endl;
+   OutputJsonString(std::cout, &alert);
+}
+
+} // namespace XrdSsiPb
+
+
+
+//! Usage exception
+
+const std::runtime_error Usage("Usage: cta_admin [command] [options]");
+#endif
+
+
+
+/*!
+ * Parse command line and process commands.
+ *
+ * Valid commands are sent to the CTA Frontend using Google Protocol Buffers 3 + XRootD SSI extensions.
+ *
+ * @param    argc[in]    The number of command-line arguments
+ * @param    argv[in]    The command-line arguments
+ */
+
+int exceptionThrowingMain(int argc, const char *const *const argv)
+{
+#if 0
+   // Verify that the Google Protocol Buffer header and linked library versions are compatible
+
+   GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+   eos::wfe::Notification notification;
+
+   // Parse the command line arguments: fill the Notification fields
+
+   bool isStderr, isJson;
+
+   fillNotification(notification, isStderr, isJson, argc, argv);
+
+   std::ostream &myout = isStderr ? std::cerr : std::cout;
+
+   if(isJson)
+   {
+      XrdSsiPb::OutputJsonString(myout, &notification);
+   }
+
+   // Obtain a Service Provider
+
+   std::string host("localhost");
+   int port = 10956;
+   std::string resource("/ctafrontend");
+
+   XrdSsiPbServiceType cta_service(host, port, resource);
+
+   // Send the Request to the Service and get a Response
+
+   eos::wfe::Response response = cta_service.Send(notification);
+
+   if(isJson)
+   {
+      XrdSsiPb::OutputJsonString(myout, &response);
+   }
+
+   // Handle responses
+
+   switch(response.type())
+   {
+      using namespace eos::wfe;
+
+      case Response::RSP_SUCCESS:         myout << response.message_txt() << std::endl; break;
+      case Response::RSP_ERR_PROTOBUF:    throw XrdSsiPb::PbException(response.message_txt());
+      case Response::RSP_ERR_CTA:         throw std::runtime_error(response.message_txt());
+      // ... define other response types in the protocol buffer (e.g. user error)
+      default:                            throw XrdSsiPb::PbException("Invalid response type.");
+   }
+
+   // Delete all global objects allocated by libprotobuf
+
+   google::protobuf::ShutdownProtobufLibrary();
+#endif
+
+   return 0;
+}
+
+
+
+/*!
+ * Start here
+ *
+ * @param    argc[in]    The number of command-line arguments
+ * @param    argv[in]    The command-line arguments
+ */
+
+int main(int argc, const char **argv)
+{
+   try {    
+      return exceptionThrowingMain(argc, argv);
+   } catch (XrdSsiPb::PbException &ex) {
+      std::cerr << "Error in Google Protocol Buffers: " << ex.what() << std::endl;
+   } catch (XrdSsiPb::XrdSsiException &ex) {
+      std::cerr << "Error from XRootD SSI Framework: " << ex.what() << std::endl;
+   } catch (std::exception &ex) {
+      std::cerr << "Caught exception: " << ex.what() << std::endl;
+   } catch (...) {
+      std::cerr << "Caught an unknown exception" << std::endl;
+   }
+
+   return cta::common::dataStructures::FrontendReturnCode::ctaErrorNoRetry;
+}
+
diff --git a/xroot_ssi_pb/XrdSsiPbDebug.hpp b/xroot_ssi_pb/XrdSsiPbDebug.hpp
index eaf44df93f..900a0d4311 100644
--- a/xroot_ssi_pb/XrdSsiPbDebug.hpp
+++ b/xroot_ssi_pb/XrdSsiPbDebug.hpp
@@ -29,7 +29,7 @@ namespace XrdSsiPb {
  * Wrapper around google::protobuf::util::MessageToJsonString() which outputs to a stream
  */
 
-static void OutputJsonString(std::ostream &os, const google::protobuf::Message *message)
+inline void OutputJsonString(std::ostream &os, const google::protobuf::Message *message)
 {
    using namespace google::protobuf::util;
 
-- 
GitLab