diff --git a/eos/messages/eos_messages.proto b/eos/messages/eos_messages.proto index 251a7227ace1d9df114a0429f50785113b94535d..c9180ce5ffe06f9bf869432b3f5816b755044558 100644 --- a/eos/messages/eos_messages.proto +++ b/eos/messages/eos_messages.proto @@ -1,127 +1,130 @@ -syntax = "proto3"; +syntax = "proto3"; package eos.wfe; -message Id { - fixed64 uid = 1; //< user identity number - string username = 2; //< user name - fixed64 gid = 3; //< group identity number - string groupname = 4; //< group name +message Clock { + uint64 sec = 1; //< seconds of a clock + uint64 nsec = 2; //< nanoseconds of a clock } message Checksum { - string value = 1; //< checksum value - string name = 2; //< checksum name + string name = 1; //< checksum name + string value = 2; //< checksum value } -message Clock { - fixed64 sec = 1; //< seconds of a clock - fixed64 nsec = 2; //< nanoseconds of a clock +message Service { + string name = 1; //< name of the service + string url = 2; //< access url of the service } -message Md { - fixed64 fid = 1; //< file/container id - fixed64 pid = 2; //< parent id - Clock ctime = 3; //< change time - Clock mtime = 4; //< modification time - Clock btime = 5; //< birth time - Clock ttime = 6; //< tree modification time - Id owner = 7; //< ownership - fixed64 size = 8; //< size - Checksum cks = 9; //< checksum information - sfixed32 mode = 10; //< mode - string lpath = 11; //< logical path - map<string, string> xattr = 12; //< xattribute map -}; +message Id { + uint64 uid = 1; //< user identity number + string username = 2; //< user name + uint64 gid = 3; //< group identity number + string groupname = 4; //< group name +} message Security { - string host = 1; //< client host - string app = 2; //< app string - string name = 3; //< sec name - string prot = 4; //< security protocol - string grps = 5; //< security grps + string host = 1; //< client host + string app = 2; //< app string + string name = 3; //< security name + string prot = 4; //< security protocol + string grps = 5; //< security grps } -message Client { - Id user = 1; //< acting client - Security sec = 2; //< client security information -} -message Service { - string name = 1; //< name of the service - string url = 2; //< access url of the service + +// +// Alert Messages +// + +message Alert { + enum Audience { EOSLOG = 0; ENDUSER = 1; } + Audience audience = 1; //< The intended audience of the error message + string message_txt = 2; //< An empty if success, else an error message } + + +// +// Messages sent from EOS to CTA Frontend +// + message Workflow { enum EventType { - NONE = 0; - OPENR = 1; - OPENW = 2; - CLOSER = 3; - CLOSEW = 4; - DELETE = 5; - PREPARE = 6;} - EventType event = 1; //< event - string queue = 2; //< queue - string wfname = 3; //< workflow - string vpath = 4; //< vpath - Service instance = 5; //< instance information - fixed64 timestamp = 6; //< event timestamp + NONE = 0; + OPENR = 1; + OPENW = 2; + CLOSER = 3; + CLOSEW = 4; + DELETE = 5; + PREPARE = 6; + } + EventType event = 1; //< event + string queue = 2; //< queue + string wfname = 3; //< workflow + string vpath = 4; //< vpath + Service instance = 5; //< instance information + uint64 timestamp = 6; //< event timestamp } -message Notification { - Workflow wf = 1; //< workflow - string turl = 2; //< transport URL - Client cli = 3; //< client information - Md file = 4; //< file meta data - Md directory = 5; //< directory meta data +message Client { + Id user = 1; //< acting client + Security sec = 2; //< client security information } -message Xattr { - enum Operation { NONE = 0; GET = 1; ADD = 2; SET = 3; DELETE = 4;} - fixed64 fid = 1; //< file id - map<string, string> xattrs = 2; //< xattribute map - Operation op = 3; //< operation to execute for this xattr map +message Transport { + string url = 1; //< transport URL } -message Tapereplica { - enum Status { NONE = 0; OFFTAPE = 1; ONTAPE = 2; ONTAPESAVE = 3;} - fixed64 fid = 1; //< file id - Status status = 2; //< state state for file ID - fixed64 size = 3; //< File size as recorded on tape for cross check - Checksum cks = 4; //< File checksum as computer while writing to tape -} +message Metadata { + uint64 fid = 1; //< file/container id + uint64 pid = 2; //< parent id + Clock ctime = 3; //< change time + Clock mtime = 4; //< modification time + Clock btime = 5; //< birth time + Clock ttime = 6; //< tree modification time + Id owner = 7; //< ownership + uint64 size = 8; //< size + Checksum cks = 9; //< checksum information + sint32 mode = 10; //< mode + string lpath = 11; //< logical path + map<string, string> xattr = 12; //< xattribute map +}; -message Error { - enum Audience { NONE = 0; EOSLOG = 1; ENDUSER = 2;} - Audience audience = 1; //< The intended audience of the error message - fixed64 code = 2; //< Zero means success, non-zero means error - string message = 3; //< An empty if success, else an error message +message Notification { + Workflow wf = 1; //< workflow + Client cli = 2; //< client information + Transport transport = 3; //< transport + Metadata file = 4; //< file meta data + Metadata directory = 5; //< directory meta data } -// The following message is used to wrap all messages sent between EOS and its -// peers. -// -// This wrapper message allows new message types to be added to the protocol in -// the future. + + // -// This wrapper message also allows EOS peers to receive non-EOS messages as -// long as the following two conditions are met: -// 1. The peer uses a wrapper message with exactly the same (simple) structure. -// 2. No two message types use the same numeric tag value. +// Messages sent from CTA Frontend to EOS // -// The structure of this message is based on the "Union Types" section of the -// following Google protocol buffers web page: + +message Response { + enum ResponseType { + RSP_SUCCESS = 0; //< Notification was queued successfully + RSP_ERR_PROTOBUF = 1; //< Framework error caused by Google Protocol Buffers layer + RSP_ERR_CTA = 2; //< Server error reported by CTA Frontend + } + ResponseType type = 1; //< Encode the type of this reply + string message_txt = 2; //< Text of the reply +} + + + // -// https://developers.google.com/protocol-buffers/docs/techniques +// Messages sent from the Tape Server to EOS // -// A protocol buffer parser cannot determine a message type based solely on its -// contents. The type field of this wrapper message provides the required -// metadata. -message Wrapper { - enum Type {NONE = 0; ERROR = 1; NOTIFICATION = 2; XATTR = 3; TAPEREPLICA = 4;} - Type type = 1; - Error error = 2; - Notification notification = 3; - Xattr xattr = 4; - Tapereplica tapereplica = 5; -} + +//message Tapereplica { +// enum Status { NONE = 0; OFFTAPE = 1; ONTAPE = 2; ONTAPESAVE = 3; } +// uint64 fid = 1; //< file id +// Status status = 2; //< status for file id +// uint64 size = 3; //< File size as recorded on tape, for cross-check +// Checksum cks = 4; //< File checksum as computer while writing to tape +//} diff --git a/xroot_plugins/CMakeLists.txt b/xroot_plugins/CMakeLists.txt index 6ccb3f8d6209a3b78845483150326282cd1e140f..49cefaa20d20b28daae532fa9620ff78d08046bd 100644 --- a/xroot_plugins/CMakeLists.txt +++ b/xroot_plugins/CMakeLists.txt @@ -33,22 +33,3 @@ INSTALL (FILES xrootd-cta.cfg DESTINATION /etc/xrootd/) INSTALL (FILES cta-frontend.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cta) install (FILES cta-frontend.logrotate DESTINATION /etc/logrotate.d RENAME cta-frontend) -set (OPAQUE_QUERY_CMD_SRC_FILES - CmdLineTool.cpp - OpaqueQueryCmd.cpp - OpaqueQueryCmdLineArgs.cpp - OpaqueQueryCmdMain.cpp) - -add_executable (cta-xrootd_plugins-opaque-query ${OPAQUE_QUERY_CMD_SRC_FILES}) -add_dependencies (cta-xrootd_plugins-opaque-query generate_notification.pb.h) -target_link_libraries (cta-xrootd_plugins-opaque-query ctacommon) - -set (WRITE_NOTIFICATION_MSG_CMD_SRC_FILES - CmdLineTool.cpp - WriteNotificationMsgCmd.cpp - WriteNotificationMsgCmdLineArgs.cpp - WriteNotificationMsgCmdMain.cpp) - -add_executable (cta-xrootd_plugins-write-notification-msg ${WRITE_NOTIFICATION_MSG_CMD_SRC_FILES}) -add_dependencies (cta-xrootd_plugins-write-notification-msg generate_notification.pb.h) -target_link_libraries (cta-xrootd_plugins-write-notification-msg ctacommon ctaeosmessages) diff --git a/xroot_plugins/OpaqueQueryCmd.cpp b/xroot_plugins/OpaqueQueryCmd.cpp deleted file mode 100644 index 096ff46c86c991a6a73377b4b954b06d2d2be853..0000000000000000000000000000000000000000 --- a/xroot_plugins/OpaqueQueryCmd.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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/>. - */ - -#include "common/make_unique.hpp" -#include "eos/messages/eos_messages.pb.h" -#include "xroot_plugins/OpaqueQueryCmd.hpp" -#include "xroot_plugins/OpaqueQueryCmdLineArgs.hpp" - -#include <fstream> -#include <iostream> -#include <stdint.h> -#include <string> -#include <XrdCl/XrdClFileSystem.hh> - -namespace cta { -namespace xroot_plugins { - -//------------------------------------------------------------------------------ -// constructor -//------------------------------------------------------------------------------ -OpaqueQueryCmd::OpaqueQueryCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream): -CmdLineTool(inStream, outStream, errStream) { -} - -//------------------------------------------------------------------------------ -// destructor -//------------------------------------------------------------------------------ -OpaqueQueryCmd::~OpaqueQueryCmd() noexcept { -} - -//------------------------------------------------------------------------------ -// exceptionThrowingMain -//------------------------------------------------------------------------------ -int OpaqueQueryCmd::exceptionThrowingMain(const int argc, char *const *const argv) { - const OpaqueQueryCmdLineArgs cmdLineArgs(argc, argv); - - if(cmdLineArgs.help) { - printUsage(m_out); - return 0; - } - - std::ifstream queryFileStream(cmdLineArgs.queryFilename, std::ios_base::binary); - if(!queryFileStream) { - m_err << "Failed to open " << cmdLineArgs.queryFilename << std::endl; - return 1; - } - std::vector<char> queryFileContents( - (std::istreambuf_iterator<char>(queryFileStream)), - (std::istreambuf_iterator<char>())); - - const std::string protocol = "xroot"; - const std::string fsUrl = protocol + ":" + "//" + cmdLineArgs.ctaHost + ":" + std::to_string(cmdLineArgs.ctaPort); - XrdCl::FileSystem fs(fsUrl, false); - - XrdCl::Buffer arg; - arg.Append(&queryFileContents[0], queryFileContents.size(), 0); - XrdCl::Buffer *response = nullptr; - const XrdCl::XRootDStatus status = fs.Query(XrdCl::QueryCode::Opaque, arg, response); - std::unique_ptr<XrdCl::Buffer> smartResponse(response); - - std::cout << "status.IsError()=" << (status.IsError() ? "true" : "false") << std::endl; - std::cout << "status.IsFatal()=" << (status.IsFatal() ? "true" : "false") << std::endl; - std::cout << "status.IsOK()=" << (status.IsOK() ? "true" : "false") << std::endl; - if(nullptr != smartResponse.get()) { - std::cout << "response->GetSize()=" << response->GetSize() << std::endl; - - std::ofstream responseFileStream(cmdLineArgs.responseFilename, std::ios_base::binary); - if(!responseFileStream) { - std::cerr << "Failed to open " << cmdLineArgs.responseFilename << std::endl; - } - const char *buf = smartResponse->GetBuffer(); - const uint32_t bufSize = smartResponse->GetSize(); - responseFileStream.write(buf, bufSize); - } - return 0; -} - -//------------------------------------------------------------------------------ -// printUsage -//------------------------------------------------------------------------------ -void OpaqueQueryCmd::printUsage(std::ostream &os) { - OpaqueQueryCmdLineArgs::printUsage(os); -} - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/OpaqueQueryCmd.hpp b/xroot_plugins/OpaqueQueryCmd.hpp deleted file mode 100644 index 47d7236f0437aec741ba8e7a0617a7afc34f5c03..0000000000000000000000000000000000000000 --- a/xroot_plugins/OpaqueQueryCmd.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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/>. - */ - -#pragma once - -#include "xroot_plugins/CmdLineTool.hpp" -#include "rdbms/Conn.hpp" - -namespace cta { -namespace xroot_plugins { - -/** - * Command-line tool to emulate EOS sending CTA a message. - */ -class OpaqueQueryCmd: public CmdLineTool { -public: - - /** - * Constructor. - * - * @param inStream Standard input stream. - * @param outStream Standard output stream. - * @param errStream Standard error stream. - */ - OpaqueQueryCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream); - - /** - * Destructor. - */ - ~OpaqueQueryCmd() noexcept; - -private: - - /** - * An exception throwing version of main(). - * - * @param argc The number of command-line arguments including the program name. - * @param argv The command-line arguments. - * @return The exit value of the program. - */ - int exceptionThrowingMain(const int argc, char *const *const argv) override; - - /** - * Prints the usage message of the command-line tool. - * - * @param os The output stream to which the usage message is to be printed. - */ - void printUsage(std::ostream &os) override; - -}; // class OpaqueQueryCmd - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/OpaqueQueryCmdLineArgs.cpp b/xroot_plugins/OpaqueQueryCmdLineArgs.cpp deleted file mode 100644 index 77e449674836be89b6e9f43901da919b7f6ad7ba..0000000000000000000000000000000000000000 --- a/xroot_plugins/OpaqueQueryCmdLineArgs.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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/>. - */ - -#include "common/exception/CommandLineNotParsed.hpp" -#include "common/utils/utils.hpp" -#include "xroot_plugins/OpaqueQueryCmdLineArgs.hpp" - -#include <getopt.h> -#include <ostream> - -namespace cta { -namespace xroot_plugins { - -//------------------------------------------------------------------------------ -// constructor -//------------------------------------------------------------------------------ -OpaqueQueryCmdLineArgs::OpaqueQueryCmdLineArgs(const int argc, char *const *const argv): - ctaPort(0), - help(false) { - - static struct option longopts[] = { - {"help", no_argument, NULL, 'h'}, - {NULL , 0, NULL, 0} - }; - - // Prevent getopt() from printing an error message if it does not recognize - // an option character - opterr = 0; - - int opt = 0; - while((opt = getopt_long(argc, argv, ":h", longopts, NULL)) != -1) { - switch(opt) { - case 'h': - help = true; - break; - case ':': // Missing parameter - { - exception::CommandLineNotParsed ex; - ex.getMessage() << "The -" << (char)opt << " option requires a parameter"; - throw ex; - } - case '?': // Unknown option - { - exception::CommandLineNotParsed ex; - if(0 == optopt) { - ex.getMessage() << "Unknown command-line option"; - } else { - ex.getMessage() << "Unknown command-line option: -" << (char)optopt; - } - throw ex; - } - default: - { - exception::CommandLineNotParsed ex; - ex.getMessage() << - "getopt_long returned the following unknown value: 0x" << - std::hex << (int)opt; - throw ex; - } - } // switch(opt) - } // while getopt_long() - - // Calculate the number of non-option ARGV-elements - const int actualNbArgs = argc - optind; - - if(help && actualNbArgs > 0) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "A command-line argument cannot be specified with the -h|--help option"; - throw ex; - } - - // There is no need to continue parsing when the help option is set - if(help) { - return; - } - - // Check the number of arguments - const int expectedNbArgs = 4; - if(actualNbArgs != expectedNbArgs) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "Wrong number of command-line arguments: excepted=" << expectedNbArgs << " actual=" << - actualNbArgs; - throw ex; - } - - ctaHost = argv[optind]; - try { - ctaPort = utils::toUint16(argv[optind + 1]); - } catch(exception::Exception &ex) { - throw exception::Exception(std::string("Invalid CTA port number: " + ex.getMessage().str())); - } - queryFilename = argv[optind+2]; - responseFilename = argv[optind+3]; -} - -//------------------------------------------------------------------------------ -// printUsage -//------------------------------------------------------------------------------ -void OpaqueQueryCmdLineArgs::printUsage(std::ostream &os) { - os << - "Description:" << std::endl << - " Sends an xrootd \"opaque query\" message to the CTA front end" << std::endl << - "Usage:" << std::endl << - " cta-xroot_plugins-opaque-query [options] ctaHost ctaPort queryFilename responseFileName" << std::endl << - "Where:" << std::endl << - " ctaHost" << std::endl << - " The network name of the host on which the CTA front end is running" << std::endl << - " ctaPort" << std::endl << - " The TCP/IP port on which the CTA front end is listening for connections" << std::endl << - " queryFilename" << std::endl << - " The name of file containing the query blob to be sent to the CTA front end" << std::endl << - " responseFilename" << std::endl << - " The name of file to which the binary responce from the CTA front end will be written" << std::endl << - "Options:" << std::endl << - " -h,--help" << std::endl << - " Prints this usage message" << std::endl << - "Example 1:" << std::endl << - " echo -n -e 'Hello\\n\\x00World' > strange.msg" << std::endl << - " cta-xrootd_plugins-opaque-query localhost 10955 strange.msg response.msg" << std::endl << - "Example 2:" << std::endl << - " cta-xrootd_plugins-write-notification-msg CLOSEW notification.msg" << std::endl << - " cta-xrootd_plugins-opaque-query localhost 10955 notification.msg response.msg" << std::endl; -} - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/OpaqueQueryCmdLineArgs.hpp b/xroot_plugins/OpaqueQueryCmdLineArgs.hpp deleted file mode 100644 index e7ebc1a85f74a045f7e7c54bb3afced5e803522c..0000000000000000000000000000000000000000 --- a/xroot_plugins/OpaqueQueryCmdLineArgs.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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/>. - */ - -#pragma once - -#include <ostream> -#include <stdint.h> -#include <string> - -namespace cta { -namespace xroot_plugins { - -/** - * Structure to store the command-line arguments of the command-line tool - * named cta-xroot_plugins-fake-eos. - */ -struct OpaqueQueryCmdLineArgs { - /** - * The name of the host on which the CTA front end is running. - */ - std::string ctaHost; - - /** - * The TCP/IP port on which the CTA front end is listening. - */ - uint16_t ctaPort; - - /** - * The name of the file containing binary the query argument to be sent to the - * CTA front end using: - * - * XrdCl::FileSystem::Query(XrdCl::QueryCode::Opaque, arg, response) - * - * Where arg is the contents of the named file. - */ - std::string queryFilename; - - /** - * The name of the file to which the binary response from the CTA front end - * will be written. - */ - std::string responseFilename; - - /** - * True if the usage message should be printed. - */ - bool help; - - /** - * Constructor that parses the specified command-line arguments. - * - * @param argc The number of command-line arguments including the name of the - * executable. - * @param argv The vector of command-line arguments. - */ - OpaqueQueryCmdLineArgs(const int argc, char *const *const argv); - - /** - * Prints the usage message of the command-line tool. - * - * @param os The output stream to which the usage message is to be printed. - */ - static void printUsage(std::ostream &os); -}; - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/OpaqueQueryCmdMain.cpp b/xroot_plugins/OpaqueQueryCmdMain.cpp deleted file mode 100644 index afd85baf9ea108b42d76ac8b0b5661a01465526b..0000000000000000000000000000000000000000 --- a/xroot_plugins/OpaqueQueryCmdMain.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/>. - */ - -#include "xroot_plugins/OpaqueQueryCmd.hpp" - -#include <iostream> - -//------------------------------------------------------------------------------ -// main -//------------------------------------------------------------------------------ -int main(const int argc, char *const *const argv) { - cta::xroot_plugins::OpaqueQueryCmd cmd(std::cin, std::cout, std::cerr); - return cmd.main(argc, argv); -} diff --git a/xroot_plugins/WriteNotificationMsgCmd.cpp b/xroot_plugins/WriteNotificationMsgCmd.cpp deleted file mode 100644 index a2f189e194bf148131a06864c38b8f3b56ebf9cc..0000000000000000000000000000000000000000 --- a/xroot_plugins/WriteNotificationMsgCmd.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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/>. - */ - -#include "common/exception/Exception.hpp" -#include "common/make_unique.hpp" -#include "common/utils/utils.hpp" -#include "xroot_plugins/WriteNotificationMsgCmd.hpp" -#include "xroot_plugins/WriteNotificationMsgCmdLineArgs.hpp" - -#include <fstream> -#include <google/protobuf/util/json_util.h> -#include <iostream> -#include <pwd.h> -#include <stdint.h> -#include <string> -#include <sys/types.h> -#include <unistd.h> - -namespace cta { -namespace xroot_plugins { - -//------------------------------------------------------------------------------ -// constructor -//------------------------------------------------------------------------------ -WriteNotificationMsgCmd::WriteNotificationMsgCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream): -CmdLineTool(inStream, outStream, errStream) { -} - -//------------------------------------------------------------------------------ -// destructor -//------------------------------------------------------------------------------ -WriteNotificationMsgCmd::~WriteNotificationMsgCmd() noexcept { -} - -//------------------------------------------------------------------------------ -// exceptionThrowingMain -//------------------------------------------------------------------------------ -int WriteNotificationMsgCmd::exceptionThrowingMain(const int argc, char *const *const argv) { - const WriteNotificationMsgCmdLineArgs cmdLineArgs(argc, argv); - - if(cmdLineArgs.help) { - printUsage(m_out); - return 0; - } - - eos::wfe::Wrapper wrapper; - wrapper.set_type(eos::wfe::Wrapper::NOTIFICATION); - wrapper.mutable_notification()->mutable_wf()->set_event(cmdLineArgs.wfEvent); - wrapper.mutable_notification()->mutable_wf()->set_queue("notification_workflow_queue"); - wrapper.mutable_notification()->mutable_wf()->set_wfname("default"); - wrapper.mutable_notification()->mutable_wf()->set_vpath("notification_workflow_vpath"); - wrapper.mutable_notification()->mutable_wf()->mutable_instance()->set_name("eosdev"); - wrapper.mutable_notification()->mutable_wf()->mutable_instance()->set_url("notification_instance_url"); - wrapper.mutable_notification()->mutable_wf()->set_timestamp(1100); - wrapper.mutable_notification()->set_turl("notification_turl"); - wrapper.mutable_notification()->mutable_cli()->mutable_user()->set_uid(1111); - wrapper.mutable_notification()->mutable_cli()->mutable_user()->set_username(getUsername()); - wrapper.mutable_notification()->mutable_cli()->mutable_user()->set_gid(1122); - wrapper.mutable_notification()->mutable_cli()->mutable_user()->set_groupname("notification_cli_user_groupname"); - wrapper.mutable_notification()->mutable_cli()->mutable_sec()->set_host("notification_cli_sec_host"); - wrapper.mutable_notification()->mutable_cli()->mutable_sec()->set_app("notification_cli_sec_app"); - wrapper.mutable_notification()->mutable_cli()->mutable_sec()->set_name("notification_cli_sec_name"); - wrapper.mutable_notification()->mutable_cli()->mutable_sec()->set_prot("notification_cli_sec_prot"); - wrapper.mutable_notification()->mutable_cli()->mutable_sec()->set_grps("notification_cli_sec_grps"); - wrapper.mutable_notification()->mutable_file()->set_fid(1133); - wrapper.mutable_notification()->mutable_file()->set_pid(1144); - wrapper.mutable_notification()->mutable_file()->mutable_ctime()->set_sec(1155); - wrapper.mutable_notification()->mutable_file()->mutable_ctime()->set_nsec(1166); - wrapper.mutable_notification()->mutable_file()->mutable_mtime()->set_sec(1177); - wrapper.mutable_notification()->mutable_file()->mutable_mtime()->set_nsec(1188); - wrapper.mutable_notification()->mutable_file()->mutable_btime()->set_sec(1199); - wrapper.mutable_notification()->mutable_file()->mutable_btime()->set_nsec(2200); - wrapper.mutable_notification()->mutable_file()->mutable_ttime()->set_sec(2211); - wrapper.mutable_notification()->mutable_file()->mutable_ttime()->set_nsec(2222); - wrapper.mutable_notification()->mutable_file()->mutable_owner()->set_uid(2233); - wrapper.mutable_notification()->mutable_file()->mutable_owner()->set_username("notification_file_owner_username"); - wrapper.mutable_notification()->mutable_file()->mutable_owner()->set_gid(2244); - wrapper.mutable_notification()->mutable_file()->mutable_owner()->set_groupname("notification_file_owner_groupname"); - wrapper.mutable_notification()->mutable_file()->set_size(2255); - wrapper.mutable_notification()->mutable_file()->mutable_cks()->set_value("notification_file_cks_value"); - wrapper.mutable_notification()->mutable_file()->mutable_cks()->set_name("notification_file_cks_name"); - wrapper.mutable_notification()->mutable_file()->set_mode(2266); - wrapper.mutable_notification()->mutable_file()->set_lpath("notification_file_lpath"); - (*wrapper.mutable_notification()->mutable_file()->mutable_xattr())["notification_file_xattr1"] = "file_xattr1_value"; - (*wrapper.mutable_notification()->mutable_file()->mutable_xattr())["notification_file_xattr2"] = "file_xattr2_value"; - if(eos::wfe::Workflow::PREPARE == cmdLineArgs.wfEvent) { - (*wrapper.mutable_notification()->mutable_file()->mutable_xattr())["sys.archiveFileId"] = "1"; - } - wrapper.mutable_notification()->mutable_directory()->set_fid(2277); - wrapper.mutable_notification()->mutable_directory()->set_pid(2288); - wrapper.mutable_notification()->mutable_directory()->mutable_ctime()->set_sec(2299); - wrapper.mutable_notification()->mutable_directory()->mutable_ctime()->set_nsec(3300); - wrapper.mutable_notification()->mutable_directory()->mutable_mtime()->set_sec(3311); - wrapper.mutable_notification()->mutable_directory()->mutable_mtime()->set_nsec(3322); - wrapper.mutable_notification()->mutable_directory()->mutable_btime()->set_sec(3333); - wrapper.mutable_notification()->mutable_directory()->mutable_btime()->set_nsec(3344); - wrapper.mutable_notification()->mutable_directory()->mutable_ttime()->set_sec(3355); - wrapper.mutable_notification()->mutable_directory()->mutable_ttime()->set_nsec(3366); - wrapper.mutable_notification()->mutable_directory()->mutable_owner()->set_uid(3377); - wrapper.mutable_notification()->mutable_directory()->mutable_owner()->set_username("notification_directory_owner_username"); - wrapper.mutable_notification()->mutable_directory()->mutable_owner()->set_gid(3377); - wrapper.mutable_notification()->mutable_directory()->mutable_owner()->set_groupname("notification_directory_owner_groupname"); - wrapper.mutable_notification()->mutable_directory()->set_size(3388); - wrapper.mutable_notification()->mutable_directory()->mutable_cks()->set_value("notification_directory_cks_value"); - wrapper.mutable_notification()->mutable_directory()->mutable_cks()->set_name("notification_directory_cks_name"); - wrapper.mutable_notification()->mutable_directory()->set_mode(3399); - wrapper.mutable_notification()->mutable_directory()->set_lpath("notification_directory_lpath"); - (*wrapper.mutable_notification()->mutable_directory()->mutable_xattr())["notification_directory_attr1"] = "directory_xattr1_value"; - (*wrapper.mutable_notification()->mutable_directory()->mutable_xattr())["notification_directory_attr2"] = "directory_xattr2_value"; - (*wrapper.mutable_notification()->mutable_directory()->mutable_xattr())["CTA_StorageClass"] = "single"; - - if(cmdLineArgs.writeJsonToStdOut) { - google::protobuf::util::JsonPrintOptions options; - options.add_whitespace = true; - options.always_print_primitive_fields = true; - std::string jsonNotification; - google::protobuf::util::MessageToJsonString(wrapper, &jsonNotification, options); - std::cout << jsonNotification; - return 0; - } - - std::ofstream messageFileStream(cmdLineArgs.filename, std::ios_base::binary); - if(!messageFileStream) { - m_err << "Failed to open " << cmdLineArgs.filename << std::endl; - return 1; - } - - wrapper.SerializeToOstream(&messageFileStream); - - return 0; -} - -//------------------------------------------------------------------------------ -// getUsername -//------------------------------------------------------------------------------ -std::string WriteNotificationMsgCmd::getUsername() { - const uid_t uid = geteuid(); - struct passwd pw; - char buf[1024]; - struct passwd *result = nullptr; - const int ret = getpwuid_r(uid, &pw, buf, sizeof(buf), &result); - - if (nullptr != result) { - return result->pw_name; - } else { - std::string errMsg; - if(0 != ret) { - errMsg = std::string("getpwuid_r() failed: ") + utils::errnoToString(ret); - } else { - errMsg = "Username not found in password database"; - } - throw exception::Exception(std::string("Failed to determine username: ") + errMsg); - } -} - -//------------------------------------------------------------------------------ -// printUsage -//------------------------------------------------------------------------------ -void WriteNotificationMsgCmd::printUsage(std::ostream &os) { - WriteNotificationMsgCmdLineArgs::printUsage(os); -} - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/WriteNotificationMsgCmd.hpp b/xroot_plugins/WriteNotificationMsgCmd.hpp deleted file mode 100644 index d323582cf6d29f7c1a4a12852c4dfd4513424bfd..0000000000000000000000000000000000000000 --- a/xroot_plugins/WriteNotificationMsgCmd.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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/>. - */ - -#pragma once - -#include "xroot_plugins/CmdLineTool.hpp" -#include "rdbms/Conn.hpp" - -namespace cta { -namespace xroot_plugins { - -/** - * Command-line tool for writing a notification message to a file. - */ -class WriteNotificationMsgCmd: public CmdLineTool { -public: - - /** - * Constructor. - * - * @param inStream Standard input stream. - * @param outStream Standard output stream. - * @param errStream Standard error stream. - */ - WriteNotificationMsgCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream); - - /** - * Destructor. - */ - ~WriteNotificationMsgCmd() noexcept; - -private: - - /** - * An exception throwing version of main(). - * - * @param argc The number of command-line arguments including the program name. - * @param argv The command-line arguments. - * @return The exit value of the program. - */ - int exceptionThrowingMain(const int argc, char *const *const argv) override; - - /** - * Returns the name of the current UNIX user. - */ - static std::string getUsername(); - - /** - * Prints the usage message of the command-line tool. - * - * @param os The output stream to which the usage message is to be printed. - */ - void printUsage(std::ostream &os) override; - -}; // class WriteNotificationMsgCmd - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/WriteNotificationMsgCmdLineArgs.cpp b/xroot_plugins/WriteNotificationMsgCmdLineArgs.cpp deleted file mode 100644 index 3ddc38c0d912525a9bb81aa7d3ebad82f590b92f..0000000000000000000000000000000000000000 --- a/xroot_plugins/WriteNotificationMsgCmdLineArgs.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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/>. - */ - -#include "common/exception/CommandLineNotParsed.hpp" -#include "common/utils/utils.hpp" -#include "xroot_plugins/WriteNotificationMsgCmdLineArgs.hpp" - -#include <algorithm> -#include <getopt.h> -#include <ostream> - -namespace cta { -namespace xroot_plugins { - -//------------------------------------------------------------------------------ -// constructor -//------------------------------------------------------------------------------ -WriteNotificationMsgCmdLineArgs::WriteNotificationMsgCmdLineArgs(const int argc, char *const *const argv): - wfEvent(eos::wfe::Workflow::NONE), - writeJsonToStdOut(false), - help(false) { - - static struct option longopts[] = { - {"help", no_argument, NULL, 'h'}, - {"json", no_argument, NULL, 'j'}, - {NULL , 0, NULL, 0} - }; - - // Prevent getopt() from printing an error message if it does not recognize - // an option character - opterr = 0; - - int opt = 0; - while((opt = getopt_long(argc, argv, ":hj", longopts, NULL)) != -1) { - switch(opt) { - case 'h': - help = true; - break; - case 'j': - writeJsonToStdOut = true; - break; - case ':': // Missing parameter - { - exception::CommandLineNotParsed ex; - ex.getMessage() << "The -" << (char)opt << " option requires a parameter"; - throw ex; - } - case '?': // Unknown option - { - exception::CommandLineNotParsed ex; - if(0 == optopt) { - ex.getMessage() << "Unknown command-line option"; - } else { - ex.getMessage() << "Unknown command-line option: -" << (char)optopt; - } - throw ex; - } - default: - { - exception::CommandLineNotParsed ex; - ex.getMessage() << - "getopt_long returned the following unknown value: 0x" << - std::hex << (int)opt; - throw ex; - } - } // switch(opt) - } // while getopt_long() - - if(help && writeJsonToStdOut) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "Specifying both -h|--help and -j|--json is not permitted"; - throw ex; - } - - // Calculate the number of non-option ARGV-elements - const int actualNbArgs = argc - optind; - - if(help && actualNbArgs > 0) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "A command-line argument cannot be specified with the -h|--help option"; - throw ex; - } - - // There is no need to continue parsing if the help option is set - if(help) { - return; - } - - if(writeJsonToStdOut) { - // Check the number of arguments - const int expectedNbArgs = 1; - if(actualNbArgs != expectedNbArgs) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "Wrong number of command-line arguments with the -j|--json argument: excepted=" << - expectedNbArgs << " actual=" << actualNbArgs; - throw ex; - } - - wfEvent = parseWfEvent(argv[optind]); - } else { - // Check the number of arguments - const int expectedNbArgs = 2; - if (actualNbArgs != expectedNbArgs) { - exception::CommandLineNotParsed ex; - ex.getMessage() << "Wrong number of command-line arguments: excepted=" << expectedNbArgs << " actual=" << - actualNbArgs; - throw ex; - } - - wfEvent = parseWfEvent(argv[optind]); - filename = argv[optind + 1]; - } -} - -//------------------------------------------------------------------------------ -// parseWfEvent -//------------------------------------------------------------------------------ -eos::wfe::Workflow::EventType WriteNotificationMsgCmdLineArgs::parseWfEvent(std::string str) { - std::transform(str.begin(), str.end(),str.begin(), ::toupper); - - if(str == "CLOSEW") { - return eos::wfe::Workflow::CLOSEW; - } else if(str == "PREPARE") { - return eos::wfe::Workflow::PREPARE; - } else { - throw cta::exception::Exception(std::string("Unknown workflow event: event=") + str); - } -} - -//------------------------------------------------------------------------------ -// printUsage -//------------------------------------------------------------------------------ -void WriteNotificationMsgCmdLineArgs::printUsage(std::ostream &os) { - os << - "Description:" << std::endl << - " Writes a \"notification\" message to the specified file" << std::endl << - "Usage:" << std::endl << - " cta-xroot_plugins-write-notification-msg event filename" << std::endl << - " cta-xroot_plugins-write-notification-msg event -j|--json" << std::endl << - " cta-xroot_plugins-write-notification-msg -h|--help" << std::endl << - "Where:" << std::endl << - " event" << std::endl << - " The type of the workflow event which is case insensitive and can" << std::endl << - " either be CLOSEW or PREPARE" << std::endl << - " filename" << std::endl << - " The name of file to which the notification message will be written." << std::endl << - " Please note that this file will be overwritten if it already exists." << std::endl << - "Options:" << std::endl << - " -h, --help" << std::endl << - " Prints this usage message" << std::endl << - " -j, --json" << std::endl << - " Prints the JSON representation of the notification message to standard out" << std::endl << - "Example 1:" << std::endl << - " cta-xrootd_plugins-write-notification-msg CLOSEW notification.msg" << std::endl << - " cat notification.msg | protoc --decode_raw" << std::endl << - "Example 2:" << std::endl << - " cta-xrootd_plugins-write-notification-msg PREPARE -j" << std::endl; -} - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/WriteNotificationMsgCmdLineArgs.hpp b/xroot_plugins/WriteNotificationMsgCmdLineArgs.hpp deleted file mode 100644 index fc6dd4396a3428bc0b380669e5d1ceff24e19b4e..0000000000000000000000000000000000000000 --- a/xroot_plugins/WriteNotificationMsgCmdLineArgs.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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/>. - */ - -#pragma once - -#include "eos/messages/eos_messages.pb.h" - -#include <ostream> -#include <stdint.h> -#include <string> - -namespace cta { -namespace xroot_plugins { - -/** - * Structure to store the command-line arguments of the command-line tool - * named cta-write-notification-msg. - */ -struct WriteNotificationMsgCmdLineArgs { - /** - * The workflow event type of the notification message. - */ - eos::wfe::Workflow::EventType wfEvent; - - /** - * The name of the file to which the notification message should be written. - */ - std::string filename; - - /** - * True if the JSON representation of the notification message should be - * written to standard out. - */ - bool writeJsonToStdOut; - - /** - * True if the usage message should be printed. - */ - bool help; - - /** - * Constructor that parses the specified command-line arguments. - * - * @param argc The number of command-line arguments including the name of the - * executable. - * @param argv The vector of command-line arguments. - */ - WriteNotificationMsgCmdLineArgs(const int argc, char *const *const argv); - - /** - * Parses the specified event string. - * - * Parsing is case insensitive. - * - * @param str The string to be parsed. - * @return The numeric equivalent of the string. - */ - static eos::wfe::Workflow::EventType parseWfEvent(std::string str); - - /** - * Prints the usage message of the command-line tool. - * - * @param os The output stream to which the usage message is to be printed. - */ - static void printUsage(std::ostream &os); -}; - -} // namespace xroot_plugins -} // namespace cta diff --git a/xroot_plugins/WriteNotificationMsgCmdMain.cpp b/xroot_plugins/WriteNotificationMsgCmdMain.cpp deleted file mode 100644 index fa468899ab07ed4b5a7ffcbebee32e466fb253e8..0000000000000000000000000000000000000000 --- a/xroot_plugins/WriteNotificationMsgCmdMain.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/>. - */ - -#include "xroot_plugins/WriteNotificationMsgCmd.hpp" - -#include <iostream> - -//------------------------------------------------------------------------------ -// main -//------------------------------------------------------------------------------ -int main(const int argc, char *const *const argv) { - cta::xroot_plugins::WriteNotificationMsgCmd cmd(std::cin, std::cout, std::cerr); - return cmd.main(argc, argv); -} diff --git a/xroot_plugins/XrdCtaFilesystem.cpp b/xroot_plugins/XrdCtaFilesystem.cpp index 4e118c8c7c87e12c10e40ce7ea440622e0f989d4..3d000daf575354b8576c66729a70065bce413d31 100644 --- a/xroot_plugins/XrdCtaFilesystem.cpp +++ b/xroot_plugins/XrdCtaFilesystem.cpp @@ -73,273 +73,6 @@ extern "C" namespace cta { namespace xroot_plugins { -//------------------------------------------------------------------------------ -// FSctl -//------------------------------------------------------------------------------ -int XrdCtaFilesystem::FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eInfo, const XrdSecEntity *client) { - std::ostringstream errMsg; - - try { - if (SFS_FSCTL_PLUGIO != cmd) { - eInfo.setErrInfo(ENOTSUP, "Not supported: cmd != SFS_FSCTL_PLUGIO"); - return SFS_ERROR; - } - - { - std::list<cta::log::Param> params; - params.push_back({"args.Arg1Len", args.Arg1Len}); - params.push_back({"args.Arg2Len", args.Arg2Len}); - params.push_back({"client->host", client->host}); - params.push_back({"client->name", client->name}); - (*m_log)(log::INFO, "FSctl called", params); - } - - if (args.Arg1 == nullptr || args.Arg1Len == 0) { - throw cta::exception::Exception("Did not receive a query argument"); - } - - const std::string msgBuffer(args.Arg1, args.Arg1Len); - eos::wfe::Wrapper msg; - if (!msg.ParseFromString(msgBuffer)) { - throw cta::exception::Exception("Failed to parse incoming wrapper message"); - } - - auto reply = processWrapperMsg(msg, client); - - const int replySize = reply->DataLen(); - eInfo.setErrInfo(replySize, reply.release()); - return SFS_DATA; - } catch(cta::exception::Exception &ex) { - errMsg << __FUNCTION__ << " failed: " << ex.getMessage().str(); - } catch(std::exception &se) { - errMsg << __FUNCTION__ << " failed: " << se.what(); - } catch(...) { - errMsg << __FUNCTION__ << " failed: Caught an unknown exception"; - } - - // Reaching this point means an exception was thrown and errMsg has been set - try { - { - std::list<cta::log::Param> params; - params.push_back({"errMsg", errMsg.str()}); - (*m_log)(log::ERR, "FSctl encountered an unexpected exception", params); - } - eos::wfe::Wrapper wrapper; - wrapper.set_type(eos::wfe::Wrapper::ERROR); - eos::wfe::Error *const error = wrapper.mutable_error(); - error->set_audience(eos::wfe::Error::EOSLOG); - error->set_code(ECANCELED); - error->set_message(errMsg.str()); - - std::string replyString = wrapper.SerializeAsString(); - auto reply = make_UniqueXrdOucBuffer(replyString.size(), replyString.c_str()); - - const int replySize = reply->DataLen(); - eInfo.setErrInfo(replySize, reply.release()); - return SFS_DATA; - } catch(...) { - eInfo.setErrInfo(ECANCELED, "Failed to create reply eos::wfe::Error message"); - return SFS_ERROR; - } -} - -//------------------------------------------------------------------------------ -// processWrapperMsg -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processWrapperMsg(const eos::wfe::Wrapper &msg, - const XrdSecEntity *const client) { - switch(msg.type()) { - case eos::wfe::Wrapper::NONE: - throw cta::exception::Exception("Cannot process a wrapped message of type NONE"); - case eos::wfe::Wrapper::NOTIFICATION: - return processNotificationMsg(msg.notification(), client); - default: - { - cta::exception::Exception ex; - ex.getMessage() << "Cannot process a wrapped message with a numeric type value of " << msg.type(); - throw ex; - } - } -} - -//------------------------------------------------------------------------------ -// processNotificationMsg -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processNotificationMsg(const eos::wfe::Notification &msg, - const XrdSecEntity *const client) { - { - std::list<cta::log::Param> params; - params.push_back({"wf.event", msg.wf().event()}); - params.push_back({"wf.queue", msg.wf().queue()}); - params.push_back({"wf.wfname", msg.wf().wfname()}); - params.push_back({"fid", msg.file().fid()}); - params.push_back({"path", msg.file().lpath()}); - (*m_log)(log::INFO, "Processing notification message", params); - } - - switch(msg.wf().event()) { - case eos::wfe::Workflow::NONE: - throw cta::exception::Exception("Cannot process a NONE workflow event"); - case eos::wfe::Workflow::OPENR: - throw cta::exception::Exception("Cannot process a OPENR workflow event"); - case eos::wfe::Workflow::OPENW: - throw cta::exception::Exception("Cannot process a OPENW workflow event"); - case eos::wfe::Workflow::CLOSER: - throw cta::exception::Exception("Cannot process a CLOSER workflow event"); - case eos::wfe::Workflow::CLOSEW: - return processCLOSEW(msg, client); - case eos::wfe::Workflow::DELETE: - throw cta::exception::Exception("Cannot process a DELETE workflow event"); - case eos::wfe::Workflow::PREPARE: - return processPREPARE(msg, client); - default: - { - cta::exception::Exception ex; - ex.getMessage() << "Workflow events with numeric value " << msg.wf().event() << " are not supported"; - throw ex; - } - } -} - -//------------------------------------------------------------------------------ -// processCLOSEW -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processCLOSEW(const eos::wfe::Notification &msg, - const XrdSecEntity *const client) { - if(msg.wf().wfname() == "default") { - return processDefaultCLOSEW(msg, client); - } else { - cta::exception::Exception ex; - ex.getMessage() << "Cannot process a CLOSEW event for a " << msg.wf().wfname() << " workflow"; - throw ex; - } -} - -//------------------------------------------------------------------------------ -// processDefaultCLOSEW -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processDefaultCLOSEW(const eos::wfe::Notification &msg, -const XrdSecEntity *const client) { - cta::common::dataStructures::DiskFileInfo diskFileInfo; - diskFileInfo.recoveryBlob = toJson(msg); - diskFileInfo.group = msg.file().owner().groupname(); - diskFileInfo.owner = msg.file().owner().username(); - diskFileInfo.path = msg.file().lpath(); - - cta::common::dataStructures::UserIdentity requester; - requester.name = msg.cli().user().username(); - requester.group = msg.cli().user().groupname(); - - std::ostringstream archiveReportURL; - archiveReportURL << "eosQuery://" << msg.wf().instance().name() << "//eos/wfe/passwd?mgm.pcmd=event&mgm.fid=" << - std::hex << msg.file().fid() << - "&mgm.logid=cta&mgm.event=archived&mgm.workflow=default&mgm.path=/eos/wfe/passwd&mgm.ruid=0&mgm.rgid=0"; - - cta::common::dataStructures::ArchiveRequest request; - request.checksumType = msg.file().cks().name(); - request.checksumValue = msg.file().cks().value(); - request.diskFileInfo = diskFileInfo; - request.diskFileID = msg.file().fid(); - request.fileSize = msg.file().size(); - request.requester = requester; - request.srcURL = msg.turl(); - request.storageClass = getDirXattr("CTA_StorageClass", msg.directory()); - request.archiveReportURL = archiveReportURL.str(); - - const std::string diskInstance = msg.wf().instance().name(); - log::LogContext lc(*m_log); - const uint64_t archiveFileId = m_scheduler->queueArchive(diskInstance, request, lc); - - eos::wfe::Wrapper wrapper; - wrapper.set_type(eos::wfe::Wrapper::XATTR); - eos::wfe::Xattr *const xattr = wrapper.mutable_xattr(); - xattr->set_fid(msg.file().fid()); - xattr->set_op(eos::wfe::Xattr::ADD); - (*xattr->mutable_xattrs())["sys.archiveFileId"] = std::to_string(archiveFileId); - - std::string replyString = wrapper.SerializeAsString(); - return make_UniqueXrdOucBuffer(replyString.size(), replyString.c_str()); -} - -//------------------------------------------------------------------------------ -// getDirXattr -//------------------------------------------------------------------------------ -std::string XrdCtaFilesystem::getDirXattr(const std::string &attributeName, const eos::wfe::Md &dir) { - const auto itor = dir.xattr().find(attributeName); - if(itor == dir.xattr().end()) { - cta::exception::Exception ex; - ex.getMessage() << "Directory " << dir.lpath() << " has no attribute named " << attributeName; - throw ex; - } - return itor->second; -} - -//------------------------------------------------------------------------------ -// processPREPARE -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processPREPARE(const eos::wfe::Notification &msg, - const XrdSecEntity *const client) { - if(msg.wf().wfname() == "default") { - auto reply = processDefaultPREPARE(msg, client); - return UniqueXrdOucBuffer(reply.release()); - } else { - cta::exception::Exception ex; - ex.getMessage() << "Cannot process a PREPARE event for a " << msg.wf().wfname() << " workflow"; - throw ex; - } -} - -//------------------------------------------------------------------------------ -// processDefaultPREPARE -//------------------------------------------------------------------------------ -XrdCtaFilesystem::UniqueXrdOucBuffer XrdCtaFilesystem::processDefaultPREPARE(const eos::wfe::Notification &msg, - const XrdSecEntity *const client) { - cta::common::dataStructures::DiskFileInfo diskFileInfo; - diskFileInfo.recoveryBlob = toJson(msg); - diskFileInfo.group = msg.file().owner().groupname(); - diskFileInfo.owner = msg.file().owner().username(); - diskFileInfo.path = msg.file().lpath(); - - cta::common::dataStructures::UserIdentity requester; - requester.name = msg.cli().user().username(); - requester.group = msg.cli().user().groupname(); - - const std::string archiveFileIdStr = getFileXattr("sys.archiveFileId", msg.file()); - - cta::common::dataStructures::RetrieveRequest request; - request.diskFileInfo = diskFileInfo; - request.archiveFileID = cta::utils::toUint64(archiveFileIdStr); - request.requester = requester; - request.dstURL = msg.turl(); - - const std::string diskInstance = msg.wf().instance().name(); - log::LogContext lc(*m_log); - m_scheduler->queueRetrieve(diskInstance, request, lc); - - eos::wfe::Wrapper wrapper; - wrapper.set_type(eos::wfe::Wrapper::ERROR); // Actually success - error code will be 0 - eos::wfe::Error *const error = wrapper.mutable_error(); - error->set_audience(eos::wfe::Error::EOSLOG); - error->set_code(0); - error->set_message(""); - - std::string replyString = wrapper.SerializeAsString(); - return make_UniqueXrdOucBuffer(replyString.size(), replyString.c_str()); -} - -//------------------------------------------------------------------------------ -// getFileXattr -//------------------------------------------------------------------------------ -std::string XrdCtaFilesystem::getFileXattr(const std::string &attributeName, const eos::wfe::Md &file) { - const auto itor = file.xattr().find(attributeName); - if(itor == file.xattr().end()) { - cta::exception::Exception ex; - ex.getMessage() << "File " << file.lpath() << " has no attribute named " << attributeName; - throw ex; - } - return itor->second; -} - //------------------------------------------------------------------------------ // newFile //------------------------------------------------------------------------------ diff --git a/xroot_plugins/XrdCtaFilesystem.hpp b/xroot_plugins/XrdCtaFilesystem.hpp index 771d9ed0ee6aae879c999e11f7625d76e7816d14..73b14d186ba3bb5eeaccf8525e8c4f7d3d5f0040 100644 --- a/xroot_plugins/XrdCtaFilesystem.hpp +++ b/xroot_plugins/XrdCtaFilesystem.hpp @@ -174,109 +174,6 @@ protected: return UniqueXrdOucBuffer(xbuf); } - /** - * Processes the specified wrapper message. - * - * @param msg The message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processWrapperMsg(const eos::wfe::Wrapper &msg, const XrdSecEntity *const client); - - /** - * Processes the specified notification message. - * - * @param msg The message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processNotificationMsg(const eos::wfe::Notification &msg, const XrdSecEntity *const client); - - /** - * Processes the specified CLOSEW workflow event. - * - * @param msg The notification message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processCLOSEW(const eos::wfe::Notification &msg, const XrdSecEntity *const client); - - /** - * Processes the specified CLOSEW workflow event triggered by an EOS user - * writing a file to disk, as opposed to a tape server writing a file to disk. - * - * A user uses the "default" workflow when they write a file to disk. A tape - * server uses the "cta" workflow when it writes a file to disk. - * - * @param msg The message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processDefaultCLOSEW(const eos::wfe::Notification &msg, const XrdSecEntity *const client); - - /** - * Processes the specified PREPARE workflow event. - * - * @param msg The notification message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processPREPARE(const eos::wfe::Notification &msg, const XrdSecEntity *const client); - - /** - * Processes the specified PREPARE workflow event for a default workflow. - * - * @param msg The notification message. - * @param client Same semantic as the XrdCtaFilesystem::FSctl() method. - * @return The result in the form of an XrdOucBuffer to be sent back to the - * client. - */ - UniqueXrdOucBuffer processDefaultPREPARE(const eos::wfe::Notification &msg, const XrdSecEntity *const client); - - /** - * Return the JSON representation of teh specified Google protocol buffer - * message. - * @param protobufMsg The Google protocol buffer message. - * @return The JSON string. - */ - template <typename T> static std::string toJson(T protobufMsg) { - google::protobuf::util::JsonPrintOptions jsonPrintOptions; - jsonPrintOptions.add_whitespace = false; - jsonPrintOptions.always_print_primitive_fields = false; - std::string json; - google::protobuf::util::MessageToJsonString(protobufMsg, &json, jsonPrintOptions); - return json; - } - - /** - * Returns the value of the specified attribute of the specified directory. - * - * This method throws an exception if the specified directory does not have - * the specified attribute. - * - * @param attributeName The name pf the attribute. - * @param dir The directory. - * @return The storage class. - */ - static std::string getDirXattr(const std::string &attributeName, const eos::wfe::Md &dir); - - /** - * Returns the value of the specified attribute of the specified file. - * - * This method throws an exception if the specified file does not have the - * specified attribute. - * - * @param attributeName The name pf the attribute. - * @param file The file. - * @return The storage class. - */ - static std::string getFileXattr(const std::string &attributeName, const eos::wfe::Md &file); - }; // XrdCtaFilesystem }}