diff --git a/cmdline/CMakeLists.txt b/cmdline/CMakeLists.txt index 3a9fc2e3af96eb0f8da5749fa0ae9052426e3633..9098c080de5c08551c43c311c821febcf6f42739 100644 --- a/cmdline/CMakeLists.txt +++ b/cmdline/CMakeLists.txt @@ -32,7 +32,12 @@ include_directories(${CMAKE_BINARY_DIR}/eos_cta ${PROTOBUF3_INCLUDE_DIRS}) # # cta-admin <admin_command> is the SSI version of "cta <admin_command>" # -add_executable(cta-admin CtaAdminCmd.cpp CtaAdminCmdParse.cpp CtaAdminTextFormatter.cpp) +add_executable(cta-admin + CtaAdminCmd.cpp + CtaAdminCmdParse.cpp + CtaAdminTextFormatter.cpp + ../common/dataStructures/DriveStatus.cpp + ../common/dataStructures/MountType.cpp) target_link_libraries(cta-admin XrdSsiPbEosCta XrdSsi-4 XrdSsiLib XrdUtils) set_property (TARGET cta-admin APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH}) diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp index 592507b405ad3ee9f9a390d5ace5381dde3f4838..a65c5bfa02c10c206ee9aaad4191c936684bdedc 100644 --- a/cmdline/CtaAdminCmd.cpp +++ b/cmdline/CtaAdminCmd.cpp @@ -75,15 +75,22 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const case Data::kAflsItem: std::cout << Log::DumpProtobuf(&record.afls_item()); break; case Data::kAflsSummary: std::cout << Log::DumpProtobuf(&record.afls_summary()); break; case Data::kArlsItem: std::cout << Log::DumpProtobuf(&record.arls_item()); break; + case Data::kDrlsItem: std::cout << Log::DumpProtobuf(&record.drls_item()); break; case Data::kFrlsItem: std::cout << Log::DumpProtobuf(&record.frls_item()); break; case Data::kFrlsSummary: std::cout << Log::DumpProtobuf(&record.frls_summary()); break; + case Data::kGmrlsItem: std::cout << Log::DumpProtobuf(&record.gmrls_item()); break; case Data::kLpaItem: std::cout << Log::DumpProtobuf(&record.lpa_item()); break; case Data::kLpaSummary: std::cout << Log::DumpProtobuf(&record.lpa_summary()); break; case Data::kLprItem: std::cout << Log::DumpProtobuf(&record.lpr_item()); break; case Data::kLprSummary: std::cout << Log::DumpProtobuf(&record.lpr_summary()); break; - case Data::kTplsItem: std::cout << Log::DumpProtobuf(&record.tpls_item()); break; - case Data::kTalsItem: std::cout << Log::DumpProtobuf(&record.tals_item()); break; + case Data::kLllsItem: std::cout << Log::DumpProtobuf(&record.llls_item()); break; + case Data::kMplsItem: std::cout << Log::DumpProtobuf(&record.mpls_item()); break; case Data::kRelsItem: std::cout << Log::DumpProtobuf(&record.rels_item()); break; + case Data::kRmrlsItem: std::cout << Log::DumpProtobuf(&record.rmrls_item()); break; + case Data::kSqItem: std::cout << Log::DumpProtobuf(&record.sq_item()); break; + case Data::kSclsItem: std::cout << Log::DumpProtobuf(&record.scls_item()); break; + case Data::kTalsItem: std::cout << Log::DumpProtobuf(&record.tals_item()); break; + case Data::kTplsItem: std::cout << Log::DumpProtobuf(&record.tpls_item()); break; default: throw std::runtime_error("Received invalid stream data from CTA Frontend."); } @@ -94,15 +101,22 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const case Data::kAflsItem: formattedText.print(record.afls_item()); break; case Data::kAflsSummary: formattedText.print(record.afls_summary()); break; case Data::kArlsItem: formattedText.print(record.arls_item()); break; + case Data::kDrlsItem: formattedText.print(record.drls_item()); break; case Data::kFrlsItem: formattedText.print(record.frls_item()); break; case Data::kFrlsSummary: formattedText.print(record.frls_summary()); break; + case Data::kGmrlsItem: formattedText.print(record.gmrls_item()); break; case Data::kLpaItem: formattedText.print(record.lpa_item()); break; case Data::kLpaSummary: formattedText.print(record.lpa_summary()); break; case Data::kLprItem: formattedText.print(record.lpr_item()); break; case Data::kLprSummary: formattedText.print(record.lpr_summary()); break; - case Data::kTplsItem: formattedText.print(record.tpls_item()); break; - case Data::kTalsItem: formattedText.print(record.tals_item()); break; + case Data::kLllsItem: formattedText.print(record.llls_item()); break; + case Data::kMplsItem: formattedText.print(record.mpls_item()); break; case Data::kRelsItem: formattedText.print(record.rels_item()); break; + case Data::kRmrlsItem: formattedText.print(record.rmrls_item()); break; + case Data::kSqItem: formattedText.print(record.sq_item()); break; + case Data::kSclsItem: formattedText.print(record.scls_item()); break; + case Data::kTalsItem: formattedText.print(record.tals_item()); break; + case Data::kTplsItem: formattedText.print(record.tpls_item()); break; default: throw std::runtime_error("Received invalid stream data from CTA Frontend."); } @@ -236,19 +250,26 @@ void CtaAdminCmd::send() const std::cout << response.message_txt(); // Print streaming response header if(!isJson()) switch(response.show_header()) { - case HeaderType::ADMIN_LS: formattedText.printAdLsHeader(); break; - case HeaderType::ARCHIVEFILE_LS: formattedText.printAfLsHeader(); break; - case HeaderType::ARCHIVEFILE_LS_SUMMARY: formattedText.printAfLsSummaryHeader(); break; - case HeaderType::ARCHIVEROUTE_LS: formattedText.printArLsHeader(); break; - case HeaderType::FAILEDREQUEST_LS: formattedText.printFrLsHeader(); break; - case HeaderType::FAILEDREQUEST_LS_SUMMARY: formattedText.printFrLsSummaryHeader(); break; - case HeaderType::LISTPENDINGARCHIVES: formattedText.printLpaHeader(); break; - case HeaderType::LISTPENDINGARCHIVES_SUMMARY: formattedText.printLpaSummaryHeader(); break; - case HeaderType::LISTPENDINGRETRIEVES: formattedText.printLprHeader(); break; - case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: formattedText.printLprSummaryHeader(); break; - case HeaderType::TAPEPOOL_LS: formattedText.printTapePoolLsHeader(); break; - case HeaderType::TAPE_LS: formattedText.printTapeLsHeader(); break; + case HeaderType::ADMIN_LS: formattedText.printAdminLsHeader(); break; + case HeaderType::ARCHIVEFILE_LS: formattedText.printArchiveFileLsHeader(); break; + case HeaderType::ARCHIVEFILE_LS_SUMMARY: formattedText.printArchiveFileLsSummaryHeader(); break; + case HeaderType::ARCHIVEROUTE_LS: formattedText.printArchiveRouteLsHeader(); break; + case HeaderType::DRIVE_LS: formattedText.printDriveLsHeader(); break; + case HeaderType::FAILEDREQUEST_LS: formattedText.printFailedRequestLsHeader(); break; + case HeaderType::FAILEDREQUEST_LS_SUMMARY: formattedText.printFailedRequestLsSummaryHeader(); break; + case HeaderType::GROUPMOUNTRULE_LS: formattedText.printGroupMountRuleLsHeader(); break; + case HeaderType::LISTPENDINGARCHIVES: formattedText.printListPendingArchivesHeader(); break; + case HeaderType::LISTPENDINGARCHIVES_SUMMARY: formattedText.printListPendingArchivesSummaryHeader(); break; + case HeaderType::LISTPENDINGRETRIEVES: formattedText.printListPendingRetrievesHeader(); break; + case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: formattedText.printListPendingRetrievesSummaryHeader(); break; + case HeaderType::LOGICALLIBRARY_LS: formattedText.printLogicalLibraryLsHeader(); break; + case HeaderType::MOUNTPOLICY_LS: formattedText.printMountPolicyLsHeader(); break; case HeaderType::REPACK_LS: formattedText.printRepackLsHeader(); break; + case HeaderType::REQUESTERMOUNTRULE_LS: formattedText.printRequesterMountRuleLsHeader(); break; + case HeaderType::SHOWQUEUES: formattedText.printShowQueuesHeader(); break; + case HeaderType::STORAGECLASS_LS: formattedText.printStorageClassLsHeader(); break; + case HeaderType::TAPE_LS: formattedText.printTapeLsHeader(); break; + case HeaderType::TAPEPOOL_LS: formattedText.printTapePoolLsHeader(); break; case HeaderType::NONE: default: break; } diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index cbfb82211698f8468d2904239c6afdb6cab9db22..5e4c146d70cbf4f238c9d3b0f808e6b8e9d2c8be 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -248,7 +248,6 @@ const std::map<std::string, OptionBoolean::Key> boolOptions = { // hasOption options { "--checkchecksum", OptionBoolean::CHECK_CHECKSUM }, { "--extended", OptionBoolean::EXTENDED }, - { "--header", OptionBoolean::SHOW_HEADER }, { "--justarchive", OptionBoolean::JUSTARCHIVE }, { "--justmove", OptionBoolean::JUSTMOVE }, { "--justaddcopies", OptionBoolean::JUSTADDCOPIES }, @@ -373,7 +372,6 @@ const Option opt_firstfseq { Option::OPT_UINT, "--firstfseq", const Option opt_force { Option::OPT_BOOL, "--force", "-f", " <\"true\" or \"false\">" }; const Option opt_force_flag { Option::OPT_FLAG, "--force", "-f", "" }; const Option opt_group { Option::OPT_STR, "--group", "-g", " <group>" }; -const Option opt_header { Option::OPT_FLAG, "--header", "-h", "" }; const Option opt_hostname_alias { Option::OPT_STR, "--name", "-n", " <host_name>", "--hostname" }; const Option opt_input { Option::OPT_STR, "--input", "-i", " <\"zero\" or \"urandom\">" }; @@ -430,10 +428,10 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_ADMIN, AdminCmd::SUBCMD_ADD }, { opt_username, opt_comment }}, {{ AdminCmd::CMD_ADMIN, AdminCmd::SUBCMD_CH }, { opt_username, opt_comment }}, {{ AdminCmd::CMD_ADMIN, AdminCmd::SUBCMD_RM }, { opt_username }}, - {{ AdminCmd::CMD_ADMIN, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_ADMIN, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_ARCHIVEFILE, AdminCmd::SUBCMD_LS }, - { opt_header.optional(), opt_archivefileid.optional(), opt_diskid.optional(), opt_copynb.optional(), + { opt_archivefileid.optional(), opt_diskid.optional(), opt_copynb.optional(), opt_vid.optional(), opt_tapepool.optional(), opt_owner.optional(), opt_group.optional(), opt_storageclass.optional(), opt_path.optional(), opt_instance.optional(), opt_all.optional(), opt_summary.optional() }}, @@ -443,7 +441,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_CH }, { opt_instance, opt_storageclass, opt_copynb, opt_tapepool.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_RM }, { opt_instance, opt_storageclass, opt_copynb }}, - {{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_ARCHIVEROUTE, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_UP }, { opt_drivename_cmd }}, {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_DOWN }, { opt_drivename_cmd, opt_force_flag.optional() }}, @@ -451,7 +449,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_RM }, { opt_drivename_cmd, opt_force_flag.optional() }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_LS }, - { opt_header.optional(), opt_justarchive.optional(), opt_justretrieve.optional(), opt_tapepool.optional(), + { opt_justarchive.optional(), opt_justretrieve.optional(), opt_tapepool.optional(), opt_vid.optional(), opt_log.optional(), opt_summary.optional() }}, {{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_SHOW }, { opt_copynb.optional() }}, {{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_RETRY }, { opt_copynb.optional() }}, @@ -462,20 +460,20 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_CH }, { opt_instance, opt_username_alias, opt_mountpolicy.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_RM }, { opt_instance, opt_username_alias }}, - {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_LISTPENDINGARCHIVES, AdminCmd::SUBCMD_NONE }, - { opt_header.optional(), opt_tapepool.optional(), opt_extended.optional() }}, + { opt_tapepool.optional(), opt_extended.optional() }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_LISTPENDINGRETRIEVES, AdminCmd::SUBCMD_NONE }, - { opt_header.optional(), opt_vid.optional(), opt_extended.optional() }}, + { opt_vid.optional(), opt_extended.optional() }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_ADD }, { opt_logicallibrary_alias, opt_disabled.optional(), opt_comment }}, {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_CH }, { opt_logicallibrary_alias, opt_disabled.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_RM }, { opt_logicallibrary_alias }}, - {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_ADD }, { opt_mountpolicy_alias, opt_archivepriority, opt_minarchiverequestage, opt_retrievepriority, @@ -485,12 +483,12 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { opt_retrievepriority.optional(), opt_minretrieverequestage.optional(), opt_maxdrivesallowed.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_RM }, { opt_mountpolicy_alias }}, - {{ AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_ADD }, { opt_vid.optional(), opt_vidfile.optional(), opt_bufferurl, opt_justmove.optional(), opt_justaddcopies.optional() }}, {{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_RM }, { opt_vid }}, - {{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_LS }, { opt_header.optional(), opt_vid.optional() }}, + {{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_LS }, { opt_vid.optional() }}, {{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_ERR }, { opt_vid }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_ADD }, @@ -498,16 +496,16 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_CH }, { opt_instance, opt_username_alias, opt_mountpolicy.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_RM }, { opt_instance, opt_username_alias }}, - {{ AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ - {{ AdminCmd::CMD_SHOWQUEUES, AdminCmd::SUBCMD_NONE }, { opt_header.optional() }}, + {{ AdminCmd::CMD_SHOWQUEUES, AdminCmd::SUBCMD_NONE }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_ADD }, { opt_instance, opt_storageclass_alias, opt_copynb, opt_comment }}, {{ AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_CH }, { opt_instance, opt_storageclass_alias, opt_copynb.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_RM }, { opt_instance, opt_storageclass_alias }}, - {{ AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_ADD }, { opt_vid, opt_mediatype, opt_vendor, opt_logicallibrary, opt_tapepool, opt_capacity, opt_disabled, opt_full, @@ -519,7 +517,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_RM }, { opt_vid }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_RECLAIM }, { opt_vid }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_LS }, - { opt_header.optional(), opt_vid.optional(), opt_mediatype.optional(), opt_vendor.optional(), + { opt_vid.optional(), opt_mediatype.optional(), opt_vendor.optional(), opt_logicallibrary.optional(), opt_tapepool.optional(), opt_vo.optional(), opt_capacity.optional(), opt_disabled.optional(), opt_full.optional(), opt_all.optional() }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_LABEL }, @@ -531,7 +529,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { { opt_tapepool_alias, opt_vo.optional(), opt_partialtapes.optional(), opt_encrypted.optional(), opt_supply.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_TAPEPOOL, AdminCmd::SUBCMD_RM }, { opt_tapepool_alias }}, - {{ AdminCmd::CMD_TAPEPOOL, AdminCmd::SUBCMD_LS }, { opt_header.optional() }}, + {{ AdminCmd::CMD_TAPEPOOL, AdminCmd::SUBCMD_LS }, { }}, }; diff --git a/cmdline/CtaAdminTextFormatter.cpp b/cmdline/CtaAdminTextFormatter.cpp index 03021b3e5a92dbc995a192611aece34113a49326..fcfe922240a4b7cf4faed6d16181871b2664bb1c 100644 --- a/cmdline/CtaAdminTextFormatter.cpp +++ b/cmdline/CtaAdminTextFormatter.cpp @@ -20,9 +20,11 @@ #include <iostream> #include <iomanip> #include <cmdline/CtaAdminTextFormatter.hpp> +#include <common/dataStructures/DriveStatusSerDeser.hpp> +#include <common/dataStructures/MountTypeSerDeser.hpp> - -namespace cta { namespace admin { +namespace cta { +namespace admin { /** ** Generic utility methods @@ -109,7 +111,7 @@ void TextFormatter::flush() { ** Output for specific commands **/ -void TextFormatter::printAdLsHeader() { +void TextFormatter::printAdminLsHeader() { push_back("HEADER"); push_back( "user", @@ -123,7 +125,7 @@ void TextFormatter::printAdLsHeader() { ); } -void TextFormatter::print(const cta::admin::AdminLsItem &adls_item) { +void TextFormatter::print(const AdminLsItem &adls_item) { push_back( adls_item.user(), adls_item.creation_log().username(), @@ -136,7 +138,7 @@ void TextFormatter::print(const cta::admin::AdminLsItem &adls_item) { ); } -void TextFormatter::printAfLsHeader() { +void TextFormatter::printArchiveFileLsHeader() { push_back("HEADER"); push_back( "archive id", @@ -159,7 +161,7 @@ void TextFormatter::printAfLsHeader() { ); } -void TextFormatter::print(const cta::admin::ArchiveFileLsItem &afls_item) { +void TextFormatter::print(const ArchiveFileLsItem &afls_item) { push_back( afls_item.af().archive_id(), afls_item.copy_nb(), @@ -181,7 +183,23 @@ void TextFormatter::print(const cta::admin::ArchiveFileLsItem &afls_item) { ); } -void TextFormatter::printArLsHeader() { +void TextFormatter::printArchiveFileLsSummaryHeader() { + push_back("HEADER"); + push_back( + "total files", + "total size" + ); +} + +void TextFormatter::print(const ArchiveFileLsSummary &afls_summary) +{ + push_back( + afls_summary.total_files(), + dataSizeToStr(afls_summary.total_size()) + ); +} + +void TextFormatter::printArchiveRouteLsHeader() { push_back("HEADER"); push_back( "instance", @@ -198,7 +216,7 @@ void TextFormatter::printArLsHeader() { ); } -void TextFormatter::print(const cta::admin::ArchiveRouteLsItem &arls_item) { +void TextFormatter::print(const ArchiveRouteLsItem &arls_item) { push_back( arls_item.instance(), arls_item.storage_class(), @@ -214,23 +232,83 @@ void TextFormatter::print(const cta::admin::ArchiveRouteLsItem &arls_item) { ); } -void TextFormatter::printAfLsSummaryHeader() { + +void TextFormatter::printDriveLsHeader() { push_back("HEADER"); push_back( - "total files", - "total size" + "library", + "drive", + "host", + "desired", + "request", + "status", + "since", + "vid", + "tapepool", + "files", + "data", + "MB/s", + "session", + "priority", + "activity", + "age" ); } -void TextFormatter::print(const cta::admin::ArchiveFileLsSummary &afls_summary) +void TextFormatter::print(const DriveLsItem &drls_item) { + //using namespace cta::common::dataStructures; + + const int DRIVE_TIMEOUT = 600; // Time after which a drive will be marked as STALE + + std::string driveStatusSince; + std::string filesTransferredInSession; + std::string bytesTransferredInSession; + std::string latestBandwidth; + std::string sessionId; + std::string timeSinceLastUpdate; + + + if(drls_item.drive_status() != DriveLsItem::UNKNOWN_DRIVE_STATUS) { + driveStatusSince = std::to_string(drls_item.drive_status_since()); + } + + 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() != DriveLsItem::UP && + drls_item.drive_status() != DriveLsItem::DOWN && + drls_item.drive_status() != DriveLsItem::UNKNOWN_DRIVE_STATUS) { + sessionId = std::to_string(drls_item.session_id()); + } + + timeSinceLastUpdate = std::to_string(drls_item.time_since_last_update()) + + (drls_item.time_since_last_update() > DRIVE_TIMEOUT ? " [STALE]" : ""); + push_back( - afls_summary.total_files(), - dataSizeToStr(afls_summary.total_size()) + drls_item.logical_library(), + drls_item.drive_name(), + drls_item.host(), + (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(), + filesTransferredInSession, + bytesTransferredInSession, + latestBandwidth, + sessionId, + drls_item.current_priority(), + drls_item.current_activity(), + timeSinceLastUpdate ); } -void TextFormatter::printFrLsHeader() { +void TextFormatter::printFailedRequestLsHeader() { push_back("HEADER"); push_back( "request type", @@ -242,7 +320,7 @@ void TextFormatter::printFrLsHeader() { ); } -void TextFormatter::print(const cta::admin::FailedRequestLsItem &frls_item) { +void TextFormatter::print(const FailedRequestLsItem &frls_item) { std::string request_type; std::string tapepool_vid; @@ -272,7 +350,7 @@ void TextFormatter::print(const cta::admin::FailedRequestLsItem &frls_item) { // displayed in the text output, only in JSON. } -void TextFormatter::printFrLsSummaryHeader() { +void TextFormatter::printFailedRequestLsSummaryHeader() { push_back("HEADER"); push_back( "request type", @@ -281,10 +359,10 @@ void TextFormatter::printFrLsSummaryHeader() { ); } -void TextFormatter::print(const cta::admin::FailedRequestLsSummary &frls_summary) { +void TextFormatter::print(const FailedRequestLsSummary &frls_summary) { std::string request_type = - frls_summary.request_type() == cta::admin::RequestType::ARCHIVE_REQUEST ? "archive" : - frls_summary.request_type() == cta::admin::RequestType::RETRIEVE_REQUEST ? "retrieve" : "total"; + frls_summary.request_type() == RequestType::ARCHIVE_REQUEST ? "archive" : + frls_summary.request_type() == RequestType::RETRIEVE_REQUEST ? "retrieve" : "total"; push_back( request_type, @@ -293,7 +371,38 @@ void TextFormatter::print(const cta::admin::FailedRequestLsSummary &frls_summary ); } -void TextFormatter::printLpaHeader() { +void TextFormatter::printGroupMountRuleLsHeader() { + push_back("HEADER"); + push_back( + "instance", + "group", + "policy", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const GroupMountRuleLsItem &gmrls_item) { + push_back( + gmrls_item.disk_instance(), + gmrls_item.group_mount_rule(), + gmrls_item.mount_policy(), + gmrls_item.creation_log().username(), + gmrls_item.creation_log().host(), + timeToStr(gmrls_item.creation_log().time()), + gmrls_item.last_modification_log().username(), + gmrls_item.last_modification_log().host(), + timeToStr(gmrls_item.last_modification_log().time()), + gmrls_item.comment() + ); +} + +void TextFormatter::printListPendingArchivesHeader() { push_back("HEADER"); push_back( "tapepool", @@ -311,7 +420,7 @@ void TextFormatter::printLpaHeader() { ); } -void TextFormatter::print(const cta::admin::ListPendingArchivesItem &lpa_item) { +void TextFormatter::print(const ListPendingArchivesItem &lpa_item) { push_back( lpa_item.tapepool(), lpa_item.af().archive_id(), @@ -328,7 +437,7 @@ void TextFormatter::print(const cta::admin::ListPendingArchivesItem &lpa_item) { ); } -void TextFormatter::printLpaSummaryHeader() { +void TextFormatter::printListPendingArchivesSummaryHeader() { push_back("HEADER"); push_back( "tapepool", @@ -337,7 +446,7 @@ void TextFormatter::printLpaSummaryHeader() { ); } -void TextFormatter::print(const cta::admin::ListPendingArchivesSummary &lpa_summary) { +void TextFormatter::print(const ListPendingArchivesSummary &lpa_summary) { push_back( lpa_summary.tapepool(), lpa_summary.total_files(), @@ -345,7 +454,7 @@ void TextFormatter::print(const cta::admin::ListPendingArchivesSummary &lpa_summ ); } -void TextFormatter::printLprHeader() { +void TextFormatter::printListPendingRetrievesHeader() { push_back("HEADER"); push_back( "vid", @@ -360,7 +469,7 @@ void TextFormatter::printLprHeader() { ); } -void TextFormatter::print(const cta::admin::ListPendingRetrievesItem &lpr_item) { +void TextFormatter::print(const ListPendingRetrievesItem &lpr_item) { push_back( lpr_item.tf().vid(), lpr_item.af().archive_id(), @@ -374,7 +483,7 @@ void TextFormatter::print(const cta::admin::ListPendingRetrievesItem &lpr_item) ); } -void TextFormatter::printLprSummaryHeader() { +void TextFormatter::printListPendingRetrievesSummaryHeader() { push_back("HEADER"); push_back( "vid", @@ -383,7 +492,7 @@ void TextFormatter::printLprSummaryHeader() { ); } -void TextFormatter::print(const cta::admin::ListPendingRetrievesSummary &lpr_summary) { +void TextFormatter::print(const ListPendingRetrievesSummary &lpr_summary) { push_back( lpr_summary.vid(), lpr_summary.total_files(), @@ -391,13 +500,248 @@ void TextFormatter::print(const cta::admin::ListPendingRetrievesSummary &lpr_sum ); } +void TextFormatter::printLogicalLibraryLsHeader() { + push_back("HEADER"); + push_back( + "library", + "disabled", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const LogicalLibraryLsItem &llls_item) { + push_back( + llls_item.name(), + llls_item.is_disabled(), + llls_item.creation_log().username(), + llls_item.creation_log().host(), + timeToStr(llls_item.creation_log().time()), + llls_item.last_modification_log().username(), + llls_item.last_modification_log().host(), + timeToStr(llls_item.last_modification_log().time()), + llls_item.comment() + ); +} + +void TextFormatter::printMountPolicyLsHeader() { + push_back("HEADER"); + push_back( + "mount policy", + "a.priority", + "a.minAge", + "r.priority", + "r.minAge", + "max drives", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const MountPolicyLsItem &mpls_item) { + push_back( + mpls_item.name(), + mpls_item.archive_priority(), + mpls_item.archive_min_request_age(), + mpls_item.retrieve_priority(), + mpls_item.retrieve_min_request_age(), + mpls_item.max_drives_allowed(), + mpls_item.creation_log().username(), + mpls_item.creation_log().host(), + timeToStr(mpls_item.creation_log().time()), + mpls_item.last_modification_log().username(), + mpls_item.last_modification_log().host(), + timeToStr(mpls_item.last_modification_log().time()), + mpls_item.comment() + ); +} + +void TextFormatter::printRepackLsHeader() { + push_back("HEADER"); + push_back( + "vid", + "repackBufferURL", + "userProvidedFiles", + "totalFilesToRetrieve", + "totalBytesToRetrieve", + "totalFilesToArchive", + "totalBytesToArchive", + "retrievedFiles", + "archivedFiles", + "failedToRetrieveFiles", + "failedToRetrieveBytes", + "failedToArchiveFiles", + "failedToArchiveBytes", + "lastExpandedFSeq", + "status" + ); +} + +void TextFormatter::print(const RepackLsItem &rels_item) { + push_back( + rels_item.vid(), + rels_item.repack_buffer_url(), + rels_item.user_provided_files(), + rels_item.total_files_to_retrieve(), + dataSizeToStr(rels_item.total_bytes_to_retrieve()), + rels_item.total_files_to_archive(), + dataSizeToStr(rels_item.total_bytes_to_archive()), + rels_item.retrieved_files(), + rels_item.archived_files(), + rels_item.failed_to_retrieve_files(), + dataSizeToStr(rels_item.failed_to_retrieve_bytes()), + rels_item.failed_to_archive_files(), + dataSizeToStr(rels_item.failed_to_retrieve_bytes()), + rels_item.last_expanded_fseq(), + rels_item.status() + ); +} + +void TextFormatter::printRequesterMountRuleLsHeader() { + push_back("HEADER"); + push_back( + "instance", + "username", + "policy", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const RequesterMountRuleLsItem &rmrls_item) { + push_back( + rmrls_item.disk_instance(), + rmrls_item.requester_mount_rule(), + rmrls_item.mount_policy(), + rmrls_item.creation_log().username(), + rmrls_item.creation_log().host(), + timeToStr(rmrls_item.creation_log().time()), + rmrls_item.last_modification_log().username(), + rmrls_item.last_modification_log().host(), + timeToStr(rmrls_item.last_modification_log().time()), + rmrls_item.comment() + ); +} + +void TextFormatter::printShowQueuesHeader() { + push_back("HEADER"); + push_back( + "type", + "tapepool", + "logical library", + "vid", + "files queued", + "data queued", + "oldest age", + "priority", + "min age", + "max drives", + "cur. mounts", + "cur. files", + "cur. data", + "MB/s", + "next mounts", + "tapes capacity", + "files on tapes", + "data on tapes", + "full tapes", + "empty tapes", + "disabled tapes", + "writable tapes" + ); +} + +void TextFormatter::print(const ShowQueuesItem &sq_item) { + std::string priority; + std::string minAge; + std::string maxDrivesAllowed; + + if(sq_item.mount_type() == ARCHIVE_FOR_USER || + sq_item.mount_type() == RETRIEVE) { + priority = std::to_string(sq_item.priority()); + minAge = std::to_string(sq_item.min_age()); + maxDrivesAllowed = std::to_string(sq_item.max_drives()); + } + + push_back( + toString(ProtobufToMountType(sq_item.mount_type())), + sq_item.tapepool(), + sq_item.logical_library(), + sq_item.vid(), + sq_item.queued_files(), + dataSizeToStr(sq_item.queued_bytes()), + sq_item.oldest_age(), + priority, + minAge, + maxDrivesAllowed, + sq_item.cur_mounts(), + sq_item.cur_files(), + dataSizeToStr(sq_item.cur_bytes()), + sq_item.bytes_per_second() / 1000000, + sq_item.next_mounts(), + dataSizeToStr(sq_item.tapes_capacity()), + sq_item.tapes_files(), + dataSizeToStr(sq_item.tapes_bytes()), + sq_item.full_tapes(), + sq_item.empty_tapes(), + sq_item.disabled_tapes(), + sq_item.writable_tapes() + ); +} + +void TextFormatter::printStorageClassLsHeader() { + push_back("HEADER"); + push_back( + "instance", + "storage class", + "number of copies", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const StorageClassLsItem &scls_item) { + push_back( + scls_item.disk_instance(), + scls_item.name(), + scls_item.nb_copies(), + scls_item.creation_log().username(), + scls_item.creation_log().host(), + timeToStr(scls_item.creation_log().time()), + scls_item.last_modification_log().username(), + scls_item.last_modification_log().host(), + timeToStr(scls_item.last_modification_log().time()), + scls_item.comment() + ); +} + void TextFormatter::printTapeLsHeader() { push_back("HEADER"); push_back( "vid", "media type", "vendor", - "logical library", + "library", "tapepool", "vo", "encryption key", @@ -421,7 +765,7 @@ void TextFormatter::printTapeLsHeader() { ); } -void TextFormatter::print(const cta::admin::TapeLsItem &tals_item) { +void TextFormatter::print(const TapeLsItem &tals_item) { push_back( tals_item.vid(), tals_item.media_type(), @@ -450,47 +794,6 @@ void TextFormatter::print(const cta::admin::TapeLsItem &tals_item) { ); } -void TextFormatter::printRepackLsHeader() { - push_back("HEADER"); - push_back( - "vid", - "repackBufferURL", - "userProvidedFiles", - "totalFilesToRetrieve", - "totalBytesToRetrieve", - "totalFilesToArchive", - "totalBytesToArchive", - "retrievedFiles", - "archivedFiles", - "failedToRetrieveFiles", - "failedToRetrieveBytes", - "failedToArchiveFiles", - "failedToArchiveBytes", - "lastExpandedFSeq", - "status" - ); -} - -void TextFormatter::print(const cta::admin::RepackLsItem &rels_item) { - push_back( - rels_item.vid(), - rels_item.repack_buffer_url(), - rels_item.user_provided_files(), - rels_item.total_files_to_retrieve(), - dataSizeToStr(rels_item.total_bytes_to_retrieve()), - rels_item.total_files_to_archive(), - dataSizeToStr(rels_item.total_bytes_to_archive()), - rels_item.retrieved_files(), - rels_item.archived_files(), - rels_item.failed_to_retrieve_files(), - dataSizeToStr(rels_item.failed_to_retrieve_bytes()), - rels_item.failed_to_archive_files(), - dataSizeToStr(rels_item.failed_to_retrieve_bytes()), - rels_item.last_expanded_fseq(), - rels_item.status() - ); -} - void TextFormatter::printTapePoolLsHeader() { push_back("HEADER"); push_back( @@ -515,7 +818,7 @@ void TextFormatter::printTapePoolLsHeader() { ); } -void TextFormatter::print(const cta::admin::TapePoolLsItem &tpls_item) +void TextFormatter::print(const TapePoolLsItem &tpls_item) { uint64_t avail = tpls_item.capacity_bytes() > tpls_item.data_bytes() ? tpls_item.capacity_bytes()-tpls_item.data_bytes() : 0; diff --git a/cmdline/CtaAdminTextFormatter.hpp b/cmdline/CtaAdminTextFormatter.hpp index 29eedde121aa15c5e25482c68f1fed3e5102f92c..533e534f5d414e4a322175f45890fbf57a20d1a0 100644 --- a/cmdline/CtaAdminTextFormatter.hpp +++ b/cmdline/CtaAdminTextFormatter.hpp @@ -44,34 +44,48 @@ public: } // Output headers - void printAdLsHeader(); - void printAfLsHeader(); - void printAfLsSummaryHeader(); - void printArLsHeader(); - void printFrLsHeader(); - void printFrLsSummaryHeader(); - void printLpaHeader(); - void printLpaSummaryHeader(); - void printLprHeader(); - void printLprSummaryHeader(); - void printTapePoolLsHeader(); - void printTapeLsHeader(); + void printAdminLsHeader(); + void printArchiveFileLsHeader(); + void printArchiveFileLsSummaryHeader(); + void printArchiveRouteLsHeader(); + void printDriveLsHeader(); + void printFailedRequestLsHeader(); + void printFailedRequestLsSummaryHeader(); + void printGroupMountRuleLsHeader(); + void printListPendingArchivesHeader(); + void printListPendingArchivesSummaryHeader(); + void printListPendingRetrievesHeader(); + void printListPendingRetrievesSummaryHeader(); + void printLogicalLibraryLsHeader(); + void printMountPolicyLsHeader(); void printRepackLsHeader(); + void printRequesterMountRuleLsHeader(); + void printShowQueuesHeader(); + void printStorageClassLsHeader(); + void printTapeLsHeader(); + void printTapePoolLsHeader(); // Output records void print(const AdminLsItem &adls_item); void print(const ArchiveFileLsItem &afls_item); void print(const ArchiveFileLsSummary &afls_summary); void print(const ArchiveRouteLsItem &afls_item); + void print(const DriveLsItem &drls_item); void print(const FailedRequestLsItem &frls_item); void print(const FailedRequestLsSummary &frls_summary); + void print(const GroupMountRuleLsItem &gmrls_item); void print(const ListPendingArchivesItem &lpa_item); void print(const ListPendingArchivesSummary &lpa_summary); void print(const ListPendingRetrievesItem &lpr_item); void print(const ListPendingRetrievesSummary &lpr_summary); - void print(const TapePoolLsItem &tpls_item); - void print(const TapeLsItem &tals_item); + void print(const LogicalLibraryLsItem &llls_item); + void print(const MountPolicyLsItem &mpls_item); void print(const RepackLsItem &rels_item); + void print(const RequesterMountRuleLsItem &rmrls_item); + void print(const ShowQueuesItem &sq_item); + void print(const StorageClassLsItem &scls_item); + void print(const TapeLsItem &tals_item); + void print(const TapePoolLsItem &tpls_item); private: //! Add a line to the buffer diff --git a/common/dataStructures/DriveStatusSerDeser.hpp b/common/dataStructures/DriveStatusSerDeser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d6d4be35e9751b302f5297e4610130da9e457569 --- /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 520023b2422e66e31ff77ba635d9e6620ccd7c0d..b10bc44baa4db205d616e9566b4288a2fd032a7a 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 0000000000000000000000000000000000000000..0e6855cd8797b612784e9d0141616f5d9e2b251b --- /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(MountType mountType) { + using namespace common::dataStructures; + + switch(mountType) { + case NO_MOUNT: return common::dataStructures::MountType::NoMount; + case ARCHIVE_FOR_USER: return common::dataStructures::MountType::ArchiveForUser; + case ARCHIVE_FOR_REPACK: return common::dataStructures::MountType::ArchiveForRepack; + case ARCHIVE_ALL_TYPES: return common::dataStructures::MountType::ArchiveAllTypes; + case RETRIEVE: return common::dataStructures::MountType::Retrieve; + case LABEL: return common::dataStructures::MountType::Label; + case UNKNOWN_MOUNT_TYPE: + default: + throw std::runtime_error("In ProtobufToMountType(): unknown mount type " + std::to_string(mountType)); + } +} + +MountType MountTypeToProtobuf(common::dataStructures::MountType mountType) { + using namespace common::dataStructures; + + switch(mountType) { + case common::dataStructures::MountType::NoMount: return NO_MOUNT; + case common::dataStructures::MountType::ArchiveForUser: return ARCHIVE_FOR_USER; + case common::dataStructures::MountType::ArchiveForRepack: return ARCHIVE_FOR_REPACK; + case common::dataStructures::MountType::ArchiveAllTypes: return ARCHIVE_ALL_TYPES; + case common::dataStructures::MountType::Retrieve: return RETRIEVE; + case common::dataStructures::MountType::Label: return LABEL; + } + return UNKNOWN_MOUNT_TYPE; +} + +}} // cta::admin diff --git a/xroot_plugins/XrdCtaAdminLs.hpp b/xroot_plugins/XrdCtaAdminLs.hpp index 1ad3dd61e57aa5b652b25c58b0aa9c39fcca3d32..4ef232b49ad44fc26b43b00eebdabfcfac812c7c 100644 --- a/xroot_plugins/XrdCtaAdminLs.hpp +++ b/xroot_plugins/XrdCtaAdminLs.hpp @@ -70,7 +70,6 @@ int AdminLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { for(bool is_buffer_full = false; !m_adminList.empty() && !is_buffer_full; m_adminList.pop_front()) { Data record; - // TapePool auto &ad = m_adminList.front(); auto ad_item = record.mutable_adls_item(); diff --git a/xroot_plugins/XrdCtaArchiveRouteLs.hpp b/xroot_plugins/XrdCtaArchiveRouteLs.hpp index 9eb9acbb2148a1d8b27b132907ccc8e4cea45fa7..3ae5e1e3ffa6096d7521dee72d5fc22c025eb6da 100644 --- a/xroot_plugins/XrdCtaArchiveRouteLs.hpp +++ b/xroot_plugins/XrdCtaArchiveRouteLs.hpp @@ -70,7 +70,6 @@ int ArchiveRouteLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { for(bool is_buffer_full = false; !m_archiveRouteList.empty() && !is_buffer_full; m_archiveRouteList.pop_front()) { Data record; - // TapePool auto &ar = m_archiveRouteList.front(); auto ar_item = record.mutable_arls_item(); diff --git a/xroot_plugins/XrdCtaDriveLs.hpp b/xroot_plugins/XrdCtaDriveLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..58aeb8000aa711978e99cd0eefdd512c9ea91e92 --- /dev/null +++ b/xroot_plugins/XrdCtaDriveLs.hpp @@ -0,0 +1,151 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Drive Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> +#include <common/dataStructures/DriveStatusSerDeser.hpp> +#include <common/dataStructures/MountTypeSerDeser.hpp> + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class DriveLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + DriveLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler, + const cta::common::dataStructures::SecurityIdentity &clientID, log::LogContext &lc); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_driveList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::DriveState> m_driveList; //!< List of drives from the scheduler + + static constexpr const char* const LOG_SUFFIX = "DriveLsStream"; //!< Identifier for log messages +}; + + +DriveLsStream::DriveLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, + cta::Scheduler &scheduler, const cta::common::dataStructures::SecurityIdentity &clientID, + log::LogContext &lc) : + XrdCtaStream(catalogue, scheduler), + m_driveList(scheduler.getDriveStates(clientID, lc)) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "DriveLsStream() constructor"); + + auto driveRegexOpt = requestMsg.getOptional(OptionString::DRIVE); + + // Dump all drives unless we specified a drive + if(driveRegexOpt) { + std::string driveRegexStr = '^' + driveRegexOpt.value() + '$'; + utils::Regex driveRegex(driveRegexStr.c_str()); + + // Remove non-matching drives from the list + for(auto dr_it = m_driveList.begin(); dr_it != m_driveList.end(); ) { + if(driveRegex.has_match(dr_it->driveName)) { + ++dr_it; + } else { + auto erase_it = dr_it; + ++dr_it; + m_driveList.erase(erase_it); + } + } + + if(m_driveList.empty()) { + throw exception::UserError(std::string("No such drive: ") + driveRegexOpt.value()); + } + } + + // Sort drives in the result set into lexicographic order + typedef decltype(*m_driveList.begin()) dStateVal_t; + m_driveList.sort([](const dStateVal_t &a, const dStateVal_t &b){ return a.driveName < b.driveName; }); +} + +int DriveLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + using namespace cta::admin; + + for(bool is_buffer_full = false; !m_driveList.empty() && !is_buffer_full; m_driveList.pop_front()) { + Data record; + + auto &dr = m_driveList.front(); + auto dr_item = record.mutable_drls_item(); + + dr_item->set_logical_library(dr.logicalLibrary); + 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(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); + dr_item->set_bytes_transferred_in_session(dr.bytesTransferredInSession); + dr_item->set_latest_bandwidth(dr.latestBandwidth); + dr_item->set_session_id(dr.sessionId); + dr_item->set_time_since_last_update(time(nullptr)-dr.lastUpdateTime); + dr_item->set_current_priority(dr.currentPriority); + dr_item->set_current_activity(dr.currentActivityAndWeight ? dr.currentActivityAndWeight.value().activity : ""); + + // set the time spent in the current state + uint64_t drive_time = time(nullptr); + + switch(dr.driveStatus) { + using namespace cta::common::dataStructures; + + case DriveStatus::Probing: drive_time -= dr.probeStartTime; break; + case DriveStatus::Up: drive_time -= dr.downOrUpStartTime; break; + case DriveStatus::Down: drive_time -= dr.downOrUpStartTime; break; + case DriveStatus::Starting: drive_time -= dr.startStartTime; break; + case DriveStatus::Mounting: drive_time -= dr.mountStartTime; break; + case DriveStatus::Transferring: drive_time -= dr.transferStartTime; break; + case DriveStatus::CleaningUp: drive_time -= dr.cleanupStartTime; break; + case DriveStatus::Unloading: drive_time -= dr.unloadStartTime; break; + case DriveStatus::Unmounting: drive_time -= dr.unmountStartTime; break; + case DriveStatus::DrainingToDisk: drive_time -= dr.drainingStartTime; break; + case DriveStatus::Shutdown: drive_time -= dr.shutdownTime; break; + case DriveStatus::Unknown: break; + } + dr_item->set_drive_status_since(drive_time); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaGroupMountRuleLs.hpp b/xroot_plugins/XrdCtaGroupMountRuleLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..38f27b5c5076574cce45cf3adcf32f91c4aa271f --- /dev/null +++ b/xroot_plugins/XrdCtaGroupMountRuleLs.hpp @@ -0,0 +1,92 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Group Mount Rule Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class GroupMountRuleLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + GroupMountRuleLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_groupMountRuleList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::RequesterGroupMountRule> m_groupMountRuleList; //!< List of group mount rules from the catalogue + + static constexpr const char* const LOG_SUFFIX = "GroupMountRuleLsStream"; //!< Identifier for log messages +}; + + +GroupMountRuleLsStream::GroupMountRuleLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_groupMountRuleList(catalogue.getRequesterGroupMountRules()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "GroupMountRuleLsStream() constructor"); +} + +int GroupMountRuleLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_groupMountRuleList.empty() && !is_buffer_full; m_groupMountRuleList.pop_front()) { + Data record; + + auto &gmr = m_groupMountRuleList.front(); + auto gmr_item = record.mutable_gmrls_item(); + + gmr_item->set_disk_instance(gmr.diskInstance); + gmr_item->set_group_mount_rule(gmr.name); + gmr_item->set_mount_policy(gmr.mountPolicy); + gmr_item->mutable_creation_log()->set_username(gmr.creationLog.username); + gmr_item->mutable_creation_log()->set_host(gmr.creationLog.host); + gmr_item->mutable_creation_log()->set_time(gmr.creationLog.time); + gmr_item->mutable_last_modification_log()->set_username(gmr.lastModificationLog.username); + gmr_item->mutable_last_modification_log()->set_host(gmr.lastModificationLog.host); + gmr_item->mutable_last_modification_log()->set_time(gmr.lastModificationLog.time); + gmr_item->set_comment(gmr.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaLogicalLibraryLs.hpp b/xroot_plugins/XrdCtaLogicalLibraryLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7df9a93e69c7e329d6c4cc335fe2053d2ed066ef --- /dev/null +++ b/xroot_plugins/XrdCtaLogicalLibraryLs.hpp @@ -0,0 +1,91 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Logical Library Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class LogicalLibraryLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + LogicalLibraryLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_logicalLibraryList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::LogicalLibrary> m_logicalLibraryList; //!< List of logical libraries from the catalogue + + static constexpr const char* const LOG_SUFFIX = "LogicalLibraryLsStream"; //!< Identifier for log messages +}; + + +LogicalLibraryLsStream::LogicalLibraryLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_logicalLibraryList(catalogue.getLogicalLibraries()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "LogicalLibraryLsStream() constructor"); +} + +int LogicalLibraryLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_logicalLibraryList.empty() && !is_buffer_full; m_logicalLibraryList.pop_front()) { + Data record; + + auto &ll = m_logicalLibraryList.front(); + auto ll_item = record.mutable_llls_item(); + + ll_item->set_name(ll.name); + ll_item->set_is_disabled(ll.isDisabled); + ll_item->mutable_creation_log()->set_username(ll.creationLog.username); + ll_item->mutable_creation_log()->set_host(ll.creationLog.host); + ll_item->mutable_creation_log()->set_time(ll.creationLog.time); + ll_item->mutable_last_modification_log()->set_username(ll.lastModificationLog.username); + ll_item->mutable_last_modification_log()->set_host(ll.lastModificationLog.host); + ll_item->mutable_last_modification_log()->set_time(ll.lastModificationLog.time); + ll_item->set_comment(ll.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaMountPolicyLs.hpp b/xroot_plugins/XrdCtaMountPolicyLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..084bad6086ac3926fdf0cd67e6059a3f82c579f9 --- /dev/null +++ b/xroot_plugins/XrdCtaMountPolicyLs.hpp @@ -0,0 +1,95 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Mount Policy Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class MountPolicyLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + MountPolicyLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_mountPolicyList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::MountPolicy> m_mountPolicyList; //!< List of mount policies from the catalogue + + static constexpr const char* const LOG_SUFFIX = "MountPolicyLsStream"; //!< Identifier for log messages +}; + + +MountPolicyLsStream::MountPolicyLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_mountPolicyList(catalogue.getMountPolicies()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "MountPolicyLsStream() constructor"); +} + +int MountPolicyLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_mountPolicyList.empty() && !is_buffer_full; m_mountPolicyList.pop_front()) { + Data record; + + auto &mp = m_mountPolicyList.front(); + auto mp_item = record.mutable_mpls_item(); + + mp_item->set_name(mp.name); + mp_item->set_archive_priority(mp.archivePriority); + mp_item->set_archive_min_request_age(mp.archiveMinRequestAge); + mp_item->set_retrieve_priority(mp.retrievePriority); + mp_item->set_retrieve_min_request_age(mp.retrieveMinRequestAge); + mp_item->set_max_drives_allowed(mp.maxDrivesAllowed); + mp_item->mutable_creation_log()->set_username(mp.creationLog.username); + mp_item->mutable_creation_log()->set_host(mp.creationLog.host); + mp_item->mutable_creation_log()->set_time(mp.creationLog.time); + mp_item->mutable_last_modification_log()->set_username(mp.lastModificationLog.username); + mp_item->mutable_last_modification_log()->set_host(mp.lastModificationLog.host); + mp_item->mutable_last_modification_log()->set_time(mp.lastModificationLog.time); + mp_item->set_comment(mp.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaRequesterMountRuleLs.hpp b/xroot_plugins/XrdCtaRequesterMountRuleLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..af455befd1f653a60be5f81926e1a1457996a31e --- /dev/null +++ b/xroot_plugins/XrdCtaRequesterMountRuleLs.hpp @@ -0,0 +1,92 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Requester Mount Rule Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class RequesterMountRuleLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + RequesterMountRuleLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_requesterMountRuleList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::RequesterMountRule> m_requesterMountRuleList; //!< List of requester mount rules from the catalogue + + static constexpr const char* const LOG_SUFFIX = "RequesterMountRuleLsStream"; //!< Identifier for log messages +}; + + +RequesterMountRuleLsStream::RequesterMountRuleLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_requesterMountRuleList(catalogue.getRequesterMountRules()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "RequesterMountRuleLsStream() constructor"); +} + +int RequesterMountRuleLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_requesterMountRuleList.empty() && !is_buffer_full; m_requesterMountRuleList.pop_front()) { + Data record; + + auto &rmr = m_requesterMountRuleList.front(); + auto rmr_item = record.mutable_rmrls_item(); + + rmr_item->set_disk_instance(rmr.diskInstance); + rmr_item->set_requester_mount_rule(rmr.name); + rmr_item->set_mount_policy(rmr.mountPolicy); + rmr_item->mutable_creation_log()->set_username(rmr.creationLog.username); + rmr_item->mutable_creation_log()->set_host(rmr.creationLog.host); + rmr_item->mutable_creation_log()->set_time(rmr.creationLog.time); + rmr_item->mutable_last_modification_log()->set_username(rmr.lastModificationLog.username); + rmr_item->mutable_last_modification_log()->set_host(rmr.lastModificationLog.host); + rmr_item->mutable_last_modification_log()->set_time(rmr.lastModificationLog.time); + rmr_item->set_comment(rmr.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaShowQueues.hpp b/xroot_plugins/XrdCtaShowQueues.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a6addb3a8f1e5fec70993ca27495046a8c710b41 --- /dev/null +++ b/xroot_plugins/XrdCtaShowQueues.hpp @@ -0,0 +1,119 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Show Queues stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> +#include <common/dataStructures/MountTypeSerDeser.hpp> + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class ShowQueuesStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + ShowQueuesStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, + cta::Scheduler &scheduler, log::LogContext &lc); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_queuesAndMountsList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::QueueAndMountSummary> m_queuesAndMountsList; //!< List of queues and mounts from the scheduler + + static constexpr const char* const LOG_SUFFIX = "ShowQueuesStream"; //!< Identifier for log messages +}; + +ShowQueuesStream::ShowQueuesStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, + cta::Scheduler &scheduler, log::LogContext &lc) : + XrdCtaStream(catalogue, scheduler), + m_queuesAndMountsList(scheduler.getQueuesAndMountSummaries(lc)) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "ShowQueuesStream() constructor"); +} + +int ShowQueuesStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + using namespace cta::admin; + + for(bool is_buffer_full = false; !m_queuesAndMountsList.empty() && !is_buffer_full; m_queuesAndMountsList.pop_front()) { + Data record; + + auto &sq = m_queuesAndMountsList.front(); + auto sq_item = record.mutable_sq_item(); + + switch(sq.mountType) { + case common::dataStructures::MountType::ArchiveForUser: + sq_item->set_priority(sq.mountPolicy.archivePriority); + sq_item->set_min_age(sq.mountPolicy.archiveMinRequestAge); + sq_item->set_max_drives(sq.mountPolicy.maxDrivesAllowed); + break; + case common::dataStructures::MountType::Retrieve: + sq_item->set_priority(sq.mountPolicy.retrievePriority); + sq_item->set_min_age(sq.mountPolicy.retrieveMinRequestAge); + sq_item->set_max_drives(sq.mountPolicy.maxDrivesAllowed); + break; + default: + break; + } + + sq_item->set_mount_type(MountTypeToProtobuf(sq.mountType)); + sq_item->set_tapepool(sq.tapePool); + sq_item->set_logical_library(sq.logicalLibrary); + sq_item->set_vid(sq.vid); + sq_item->set_queued_files(sq.filesQueued); + sq_item->set_queued_bytes(sq.bytesQueued); + sq_item->set_oldest_age(sq.oldestJobAge); + sq_item->set_cur_mounts(sq.currentMounts); + sq_item->set_cur_files(sq.currentFiles); + sq_item->set_cur_bytes(sq.currentBytes); + sq_item->set_bytes_per_second(sq.latestBandwidth); + sq_item->set_next_mounts(sq.nextMounts); + sq_item->set_tapes_capacity(sq.tapesCapacity); + sq_item->set_tapes_files(sq.filesOnTapes); + sq_item->set_tapes_bytes(sq.dataOnTapes); + sq_item->set_full_tapes(sq.fullTapes); + sq_item->set_empty_tapes(sq.emptyTapes); + sq_item->set_disabled_tapes(sq.disabledTapes); + sq_item->set_writable_tapes(sq.writableTapes); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaStorageClassLs.hpp b/xroot_plugins/XrdCtaStorageClassLs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9490f801cfbfa5353d82dd0c61633d5659ea93db --- /dev/null +++ b/xroot_plugins/XrdCtaStorageClassLs.hpp @@ -0,0 +1,92 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA Storage Class Ls stream implementation + * @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 <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "tapepool ls" command + */ +class StorageClassLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + StorageClassLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_storageClassList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::StorageClass> m_storageClassList; //!< List of storage classes from the catalogue + + static constexpr const char* const LOG_SUFFIX = "StorageClassLsStream"; //!< Identifier for log messages +}; + + +StorageClassLsStream::StorageClassLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_storageClassList(catalogue.getStorageClasses()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "StorageClassLsStream() constructor"); +} + +int StorageClassLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_storageClassList.empty() && !is_buffer_full; m_storageClassList.pop_front()) { + Data record; + + auto &sc = m_storageClassList.front(); + auto sc_item = record.mutable_scls_item(); + + sc_item->set_disk_instance(sc.diskInstance); + sc_item->set_name(sc.name); + sc_item->set_nb_copies(sc.nbCopies); + sc_item->mutable_creation_log()->set_username(sc.creationLog.username); + sc_item->mutable_creation_log()->set_host(sc.creationLog.host); + sc_item->mutable_creation_log()->set_time(sc.creationLog.time); + sc_item->mutable_last_modification_log()->set_username(sc.lastModificationLog.username); + sc_item->mutable_last_modification_log()->set_host(sc.lastModificationLog.host); + sc_item->mutable_last_modification_log()->set_time(sc.lastModificationLog.time); + sc_item->set_comment(sc.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdCtaTapePoolLs.hpp b/xroot_plugins/XrdCtaTapePoolLs.hpp index 4cd527fd2fb2afc0ce61cf26c7122c2cbbb81d1b..f429df10ea137630f82b7acadb82f1adbb27085b 100644 --- a/xroot_plugins/XrdCtaTapePoolLs.hpp +++ b/xroot_plugins/XrdCtaTapePoolLs.hpp @@ -70,7 +70,6 @@ int TapePoolLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { for(bool is_buffer_full = false; !m_tapePoolList.empty() && !is_buffer_full; m_tapePoolList.pop_front()) { Data record; - // TapePool auto &tp = m_tapePoolList.front(); auto tp_item = record.mutable_tpls_item(); diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp index 626fbdd4bc9e70fb7f1b0af333c47bb303903c4e..049366a0dd3806d3df09acc192195b24c0d236d7 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp @@ -1,7 +1,7 @@ /*! * @project The CERN Tape Archive (CTA) * @brief XRootD EOS Notification handler - * @copyright Copyright 2017 CERN + * @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 @@ -16,25 +16,26 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <iomanip> // for setw - -#include <common/utils/utils.hpp> -#include <common/utils/Regex.hpp> - #include <XrdSsiPbException.hpp> using XrdSsiPb::PbException; #include <cmdline/CtaAdminCmdParse.hpp> +#include "XrdSsiCtaRequestMessage.hpp" #include "XrdCtaAdminLs.hpp" #include "XrdCtaArchiveFileLs.hpp" #include "XrdCtaArchiveRouteLs.hpp" +#include "XrdCtaDriveLs.hpp" #include "XrdCtaFailedRequestLs.hpp" +#include "XrdCtaGroupMountRuleLs.hpp" #include "XrdCtaListPendingQueue.hpp" -#include "XrdCtaTapePoolLs.hpp" -#include "XrdSsiCtaRequestMessage.hpp" -#include "XrdCtaTapeLs.hpp" +#include "XrdCtaLogicalLibraryLs.hpp" +#include "XrdCtaMountPolicyLs.hpp" #include "XrdCtaRepackLs.hpp" - +#include "XrdCtaRequesterMountRuleLs.hpp" +#include "XrdCtaShowQueues.hpp" +#include "XrdCtaTapeLs.hpp" +#include "XrdCtaStorageClassLs.hpp" +#include "XrdCtaTapePoolLs.hpp" namespace cta { namespace xrd { @@ -44,7 +45,6 @@ const char* const TEXT_RED = "\x1b[31;1m"; const char* const TEXT_NORMAL = "\x1b[0m\n"; - /* * Convert AdminCmd <Cmd, SubCmd> pair to an integer so that it can be used in a switch statement */ @@ -53,33 +53,6 @@ constexpr unsigned int cmd_pair(cta::admin::AdminCmd::Cmd cmd, cta::admin::Admin } - -/* - * Helper function to convert time to string - */ -static std::string timeToString(const time_t &time) -{ - std::string timeString(ctime(&time)); - timeString.resize(timeString.size()-1); //remove newline - return timeString; -} - - - -/* - * Helper function to convert bytes to Mb and return the result as a string - */ -static std::string bytesToMbString(uint64_t bytes) -{ - long double mBytes = static_cast<long double>(bytes)/(1000.0*1000.0); - - std::ostringstream oss; - oss << std::setprecision(2) << std::fixed << mBytes; - return oss.str(); -} - - - void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Response &response, XrdSsiStream* &stream) { // Branch on the Request payload type @@ -138,7 +111,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processDrive_Down(response); break; case cmd_pair(AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_LS): - processDrive_Ls(response); + processDrive_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_RM): processDrive_Rm(response); @@ -156,7 +129,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processGroupMountRule_Rm(response); break; case cmd_pair(AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_LS): - processGroupMountRule_Ls(response); + processGroupMountRule_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_LISTPENDINGARCHIVES, AdminCmd::SUBCMD_NONE): processListPendingArchives(response, stream); @@ -174,7 +147,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processLogicalLibrary_Rm(response); break; case cmd_pair(AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_LS): - processLogicalLibrary_Ls(response); + processLogicalLibrary_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_ADD): processMountPolicy_Add(response); @@ -186,7 +159,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processMountPolicy_Rm(response); break; case cmd_pair(AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_LS): - processMountPolicy_Ls(response); + processMountPolicy_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_ADD): processRepack_Add(response); @@ -210,10 +183,10 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processRequesterMountRule_Rm(response); break; case cmd_pair(AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_LS): - processRequesterMountRule_Ls(response); + processRequesterMountRule_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_SHOWQUEUES, AdminCmd::SUBCMD_NONE): - processShowQueues(response); + processShowQueues(response, stream); break; case cmd_pair(AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_ADD): processStorageClass_Add(response); @@ -225,7 +198,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons processStorageClass_Rm(response); break; case cmd_pair(AdminCmd::CMD_STORAGECLASS, AdminCmd::SUBCMD_LS): - processStorageClass_Ls(response); + processStorageClass_Ls(response, stream); break; case cmd_pair(AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_ADD): processTape_Add(response); @@ -801,112 +774,15 @@ void RequestMessage::processDrive_Down(cta::xrd::Response &response) -void RequestMessage::processDrive_Ls(cta::xrd::Response &response) +void RequestMessage::processDrive_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - const int DRIVE_TIMEOUT = 600; - - std::stringstream cmdlineOutput; - - // Dump all drives unless we specified a drive - bool hasRegex = false; - bool driveFound = false; - - auto driveRegexOpt = getOptional(OptionString::DRIVE, &hasRegex); - std::string driveRegexStr = hasRegex ? '^' + driveRegexOpt.value() + '$' : "."; - utils::Regex driveRegex(driveRegexStr.c_str()); - - auto driveStates = m_scheduler.getDriveStates(m_cliIdentity, m_lc); - if (!driveStates.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> headers = { - "library","drive","host","desired","request","status","since","vid","tapepool","files", - "MBytes","MB/s","session","priority","activity","age" - }; - responseTable.push_back(headers); - - typedef decltype(*driveStates.begin()) dStateVal_t; - driveStates.sort([](const dStateVal_t &a, const dStateVal_t &b){ return a.driveName < b.driveName; }); - - for (auto ds: driveStates) - { - if(!driveRegex.has_match(ds.driveName)) continue; - driveFound = true; - - auto timeSinceLastUpdate_s = time(nullptr) - ds.lastUpdateTime; - - std::vector<std::string> currentRow; - currentRow.push_back(ds.logicalLibrary); - currentRow.push_back(ds.driveName); - currentRow.push_back(ds.host); - currentRow.push_back(ds.desiredDriveState.up ? "Up" : "Down"); - currentRow.push_back(cta::common::dataStructures::toString(ds.mountType)); - currentRow.push_back(cta::common::dataStructures::toString(ds.driveStatus)); - - // print the time spent in the current state - unsigned long long drive_time = time(nullptr); - - switch(ds.driveStatus) { - using namespace cta::common::dataStructures; - - case DriveStatus::Probing: drive_time -= ds.probeStartTime; break; - case DriveStatus::Up: - case DriveStatus::Down: drive_time -= ds.downOrUpStartTime; break; - case DriveStatus::Starting: drive_time -= ds.startStartTime; break; - case DriveStatus::Mounting: drive_time -= ds.mountStartTime; break; - case DriveStatus::Transferring: drive_time -= ds.transferStartTime; break; - case DriveStatus::CleaningUp: drive_time -= ds.cleanupStartTime; break; - case DriveStatus::Unloading: drive_time -= ds.unloadStartTime; break; - case DriveStatus::Unmounting: drive_time -= ds.unmountStartTime; break; - case DriveStatus::DrainingToDisk: drive_time -= ds.drainingStartTime; break; - case DriveStatus::Shutdown: drive_time -= ds.shutdownTime; break; - case DriveStatus::Unknown: break; - } - currentRow.push_back(ds.driveStatus == cta::common::dataStructures::DriveStatus::Unknown ? "-" : - std::to_string(drive_time)); - - currentRow.push_back(ds.currentVid == "" ? "-" : ds.currentVid); - currentRow.push_back(ds.currentTapePool == "" ? "-" : ds.currentTapePool); - - switch (ds.driveStatus) { - case cta::common::dataStructures::DriveStatus::Transferring: - currentRow.push_back(std::to_string(static_cast<unsigned long long>(ds.filesTransferredInSession))); - currentRow.push_back(bytesToMbString(ds.bytesTransferredInSession)); - currentRow.push_back(bytesToMbString(ds.latestBandwidth)); - break; - default: - currentRow.push_back("-"); - currentRow.push_back("-"); - currentRow.push_back("-"); - } - switch(ds.driveStatus) { - case cta::common::dataStructures::DriveStatus::Up: - case cta::common::dataStructures::DriveStatus::Down: - case cta::common::dataStructures::DriveStatus::Unknown: - currentRow.push_back("-"); - break; - default: - currentRow.push_back(std::to_string(static_cast<unsigned long long>(ds.sessionId))); - } - currentRow.push_back(std::to_string(ds.currentPriority)); - currentRow.push_back(ds.currentActivityAndWeight?ds.currentActivityAndWeight.value().activity: "-"); - currentRow.push_back(std::to_string(timeSinceLastUpdate_s) + - (timeSinceLastUpdate_s > DRIVE_TIMEOUT ? " [STALE]" : "")); - responseTable.push_back(currentRow); - } - - if (hasRegex && !driveFound) { - throw cta::exception::UserError(std::string("No such drive: ") + driveRegexOpt.value()); - } + using namespace cta::admin; - m_option_bool[OptionBoolean::SHOW_HEADER] = true; - cmdlineOutput<< formatResponse(responseTable); - } + // Create a XrdSsi stream object to return the results + stream = new DriveLsStream(*this, m_catalogue, m_scheduler, m_cliIdentity, m_lc); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::DRIVE_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1020,36 +896,14 @@ void RequestMessage::processGroupMountRule_Rm(cta::xrd::Response &response) -void RequestMessage::processGroupMountRule_Ls(cta::xrd::Response &response) +void RequestMessage::processGroupMountRule_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; + using namespace cta::admin; - std::list<cta::common::dataStructures::RequesterGroupMountRule> list = m_catalogue.getRequesterGroupMountRules(); + stream = new GroupMountRuleLsStream(*this, m_catalogue, m_scheduler); - if(!list.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "instance","group","policy","c.user","c.host","c.time","m.user","m.host","m.time","comment" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for(auto it = list.cbegin(); it != list.cend(); it++) - { - std::vector<std::string> currentRow; - currentRow.push_back(it->diskInstance); - currentRow.push_back(it->name); - currentRow.push_back(it->mountPolicy); - addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog); - currentRow.push_back(it->comment); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } - - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::GROUPMOUNTRULE_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1134,34 +988,15 @@ void RequestMessage::processLogicalLibrary_Rm(cta::xrd::Response &response) -void RequestMessage::processLogicalLibrary_Ls(cta::xrd::Response &response) +void RequestMessage::processLogicalLibrary_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; - - std::list<cta::common::dataStructures::LogicalLibrary> list = m_catalogue.getLogicalLibraries(); + using namespace cta::admin; - if(!list.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "name","disabled","c.user","c.host","c.time","m.user","m.host","m.time","comment" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for(auto it = list.cbegin(); it != list.cend(); it++) { - std::vector<std::string> currentRow; - currentRow.push_back(it->name); - currentRow.push_back(std::to_string(it->isDisabled)); - addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog); - currentRow.push_back(it->comment); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } + // Create a XrdSsi stream object to return the results + stream = new LogicalLibraryLsStream(*this, m_catalogue, m_scheduler); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::LOGICALLIBRARY_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1235,39 +1070,15 @@ void RequestMessage::processMountPolicy_Rm(cta::xrd::Response &response) -void RequestMessage::processMountPolicy_Ls(cta::xrd::Response &response) +void RequestMessage::processMountPolicy_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; - - std::list<cta::common::dataStructures::MountPolicy> list= m_catalogue.getMountPolicies(); + using namespace cta::admin; - if(!list.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "mount policy","a.priority","a.minAge","r.priority","r.minAge","max drives","c.user","c.host","c.time","m.user","m.host","m.time","comment" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for(auto it = list.cbegin(); it != list.cend(); it++) - { - std::vector<std::string> currentRow; - currentRow.push_back(it->name); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->archivePriority))); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->archiveMinRequestAge))); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->retrievePriority))); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->retrieveMinRequestAge))); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->maxDrivesAllowed))); - addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog); - currentRow.push_back(it->comment); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } + // Create a XrdSsi stream object to return the results + stream = new MountPolicyLsStream(*this, m_catalogue, m_scheduler); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::MOUNTPOLICY_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1407,100 +1218,27 @@ void RequestMessage::processRequesterMountRule_Rm(cta::xrd::Response &response) -void RequestMessage::processRequesterMountRule_Ls(cta::xrd::Response &response) +void RequestMessage::processRequesterMountRule_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; - - std::list<cta::common::dataStructures::RequesterMountRule> list = m_catalogue.getRequesterMountRules(); + using namespace cta::admin; - if(!list.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "instance","username","policy","c.user","c.host","c.time","m.user","m.host","m.time","comment" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for(auto it = list.cbegin(); it != list.cend(); it++) { - std::vector<std::string> currentRow; - currentRow.push_back(it->diskInstance); - currentRow.push_back(it->name); - currentRow.push_back(it->mountPolicy); - addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog); - currentRow.push_back(it->comment); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } + stream = new RequesterMountRuleLsStream(*this, m_catalogue, m_scheduler); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::REQUESTERMOUNTRULE_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } -void RequestMessage::processShowQueues(cta::xrd::Response &response) +void RequestMessage::processShowQueues(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; - - auto queuesAndMounts = m_scheduler.getQueuesAndMountSummaries(m_lc); + using namespace cta::admin; - if(!queuesAndMounts.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "type","tapepool","logical library","vid","files queued","MBytes queued","oldest age","priority", - "min age","max drives","cur. mounts","cur. files","cur. MBytes","MB/s","next mounts","tapes capacity", - "files on tapes","MBytes on tapes","full tapes","empty tapes","disabled tapes","writables tapes" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for (auto & q: queuesAndMounts) - { - const uint64_t MBytes = 1000 * 1000; - - std::vector<std::string> currentRow; - currentRow.push_back(common::dataStructures::toString(q.mountType)); - currentRow.push_back(q.tapePool); - currentRow.push_back(q.logicalLibrary); - currentRow.push_back(q.vid); - currentRow.push_back(std::to_string(q.filesQueued)); - currentRow.push_back(bytesToMbString(q.bytesQueued)); - currentRow.push_back(std::to_string(q.oldestJobAge)); - if (common::dataStructures::MountType::ArchiveForUser == q.mountType) { - currentRow.push_back(std::to_string(q.mountPolicy.archivePriority)); - currentRow.push_back(std::to_string(q.mountPolicy.archiveMinRequestAge)); - currentRow.push_back(std::to_string(q.mountPolicy.maxDrivesAllowed)); - } else if (common::dataStructures::MountType::Retrieve == q.mountType) { - currentRow.push_back(std::to_string(q.mountPolicy.retrievePriority)); - currentRow.push_back(std::to_string(q.mountPolicy.retrieveMinRequestAge)); - currentRow.push_back(std::to_string(q.mountPolicy.maxDrivesAllowed)); - } else { - currentRow.push_back("-"); - currentRow.push_back("-"); - currentRow.push_back("-"); - } - currentRow.push_back(std::to_string(q.currentMounts)); - currentRow.push_back(std::to_string(q.currentFiles)); - currentRow.push_back(bytesToMbString(q.currentBytes)); - currentRow.push_back(bytesToMbString(q.latestBandwidth)); - currentRow.push_back(std::to_string(q.nextMounts)); - currentRow.push_back(std::to_string(q.tapesCapacity/MBytes)); - currentRow.push_back(std::to_string(q.filesOnTapes)); - currentRow.push_back(bytesToMbString(q.dataOnTapes)); - currentRow.push_back(std::to_string(q.fullTapes)); - currentRow.push_back(std::to_string(q.emptyTapes)); - currentRow.push_back(std::to_string(q.disabledTapes)); - currentRow.push_back(std::to_string(q.writableTapes)); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } + // Create a XrdSsi stream object to return the results + stream = new ShowQueuesStream(*this, m_catalogue, m_scheduler, m_lc); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::SHOWQUEUES); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1558,35 +1296,15 @@ void RequestMessage::processStorageClass_Rm(cta::xrd::Response &response) -void RequestMessage::processStorageClass_Ls(cta::xrd::Response &response) +void RequestMessage::processStorageClass_Ls(cta::xrd::Response &response, XrdSsiStream* &stream) { - using namespace cta::admin; - - std::stringstream cmdlineOutput; - - std::list<cta::common::dataStructures::StorageClass> list = m_catalogue.getStorageClasses(); + using namespace cta::admin; - if(!list.empty()) - { - std::vector<std::vector<std::string>> responseTable; - std::vector<std::string> header = { - "instance","storage class","number of copies","c.user","c.host","c.time","m.user","m.host","m.time","comment" - }; - if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header); - for(auto it = list.cbegin(); it != list.cend(); it++) { - std::vector<std::string> currentRow; - currentRow.push_back(it->diskInstance); - currentRow.push_back(it->name); - currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->nbCopies))); - addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog); - currentRow.push_back(it->comment); - responseTable.push_back(currentRow); - } - cmdlineOutput << formatResponse(responseTable); - } + // Create a XrdSsi stream object to return the results + stream = new StorageClassLsStream(*this, m_catalogue, m_scheduler); - response.set_message_txt(cmdlineOutput.str()); - response.set_type(cta::xrd::Response::RSP_SUCCESS); + response.set_show_header(HeaderType::STORAGECLASS_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -1822,52 +1540,6 @@ std::string RequestMessage::setDriveState(const std::string ®ex, DriveState d } - -std::string RequestMessage::formatResponse(const std::vector<std::vector<std::string>> &responseTable) const -{ - bool has_header = has_flag(cta::admin::OptionBoolean::SHOW_HEADER); - - if(responseTable.empty() || responseTable.at(0).empty()) return ""; - - std::vector<int> columnSizes; - - for(uint j = 0; j < responseTable.at(0).size(); j++) { //for each column j - uint columnSize = 0; - for(uint i = 0; i<responseTable.size(); i++) { //for each row i - if(responseTable.at(i).at(j).size() > columnSize) { - columnSize = responseTable.at(i).at(j).size(); - } - } - columnSizes.push_back(columnSize);//loops here - } - std::stringstream responseSS; - for(auto row = responseTable.cbegin(); row != responseTable.cend(); row++) { - if(has_header && row == responseTable.cbegin()) responseSS << "\x1b[31;1m"; - for(uint i = 0; i<row->size(); i++) { - responseSS << std::string(i ? " " : "") << std::setw(columnSizes.at(i)) << row->at(i); - } - if(has_header && row == responseTable.cbegin()) responseSS << "\x1b[0m" << std::endl; - else responseSS << std::endl; - } - return responseSS.str(); -} - - - -void RequestMessage::addLogInfoToResponseRow(std::vector<std::string> &responseRow, - const cta::common::dataStructures::EntryLog &creationLog, - const cta::common::dataStructures::EntryLog &lastModificationLog) const -{ - responseRow.push_back(creationLog.username); - responseRow.push_back(creationLog.host); - responseRow.push_back(timeToString(creationLog.time)); - responseRow.push_back(lastModificationLog.username); - responseRow.push_back(lastModificationLog.host); - responseRow.push_back(timeToString(lastModificationLog.time)); -} - - - void RequestMessage::importOptions(const cta::admin::AdminCmd &admincmd) { // Validate the Protocol Buffer diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp index 8515f9aba4f0c7a4495989f9a2eb0df24d3249ef..0d08dbcfc1250fc9ebaf870864fbac3108dce032 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp @@ -1,7 +1,7 @@ /*! * @project The CERN Tape Archive (CTA) * @brief CTA Frontend Message handler - * @copyright Copyright 2017 CERN + * @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 @@ -24,7 +24,6 @@ #include "cta_frontend.pb.h" - namespace cta { namespace xrd { /*! @@ -33,264 +32,244 @@ namespace cta { namespace xrd { class RequestMessage { public: - RequestMessage(const XrdSsiEntity &client, const XrdSsiCtaServiceProvider *service) : - m_scheddb (service->getSchedDb()), - m_catalogue(service->getCatalogue()), - m_scheduler(service->getScheduler()), - m_lc (service->getLogContext()) { - m_cliIdentity.username = client.name; - m_cliIdentity.host = client.host; + RequestMessage(const XrdSsiEntity &client, const XrdSsiCtaServiceProvider *service) : + m_scheddb (service->getSchedDb()), + m_catalogue(service->getCatalogue()), + m_scheduler(service->getScheduler()), + m_lc (service->getLogContext()) { + m_cliIdentity.username = client.name; + m_cliIdentity.host = client.host; - // Map the client protocol string to an enum value - auto proto_it = m_protomap.find(client.prot); - m_protocol = proto_it != m_protomap.end() ? proto_it->second : Protocol::OTHER; - } + // Map the client protocol string to an enum value + auto proto_it = m_protomap.find(client.prot); + m_protocol = proto_it != m_protomap.end() ? proto_it->second : Protocol::OTHER; + } - /*! - * Process a Notification request or an Admin command request - * - * @param[in] request - * @param[out] response Response protocol buffer - * @param[out] stream Reference to Response stream pointer - */ - void process(const cta::xrd::Request &request, cta::xrd::Response &response, XrdSsiStream* &stream); + /*! + * Process a Notification request or an Admin command request + * + * @param[in] request + * @param[out] response Response protocol buffer + * @param[out] stream Reference to Response stream pointer + */ + void process(const cta::xrd::Request &request, cta::xrd::Response &response, XrdSsiStream* &stream); - /*! - * Get a required option - */ - const std::string &getRequired(cta::admin::OptionString::Key key) const { - return m_option_str.at(key); - } - const std::vector<std::string> &getRequired(cta::admin::OptionStrList::Key key) const { - return m_option_str_list.at(key); - } - const uint64_t &getRequired(cta::admin::OptionUInt64::Key key) const { - return m_option_uint64.at(key); - } - const bool &getRequired(cta::admin::OptionBoolean::Key key) const { - return m_option_bool.at(key); - } + /*! + * Get a required option + */ + const std::string &getRequired(cta::admin::OptionString::Key key) const { + return m_option_str.at(key); + } + const std::vector<std::string> &getRequired(cta::admin::OptionStrList::Key key) const { + return m_option_str_list.at(key); + } + const uint64_t &getRequired(cta::admin::OptionUInt64::Key key) const { + return m_option_uint64.at(key); + } + const bool &getRequired(cta::admin::OptionBoolean::Key key) const { + return m_option_bool.at(key); + } - /*! - * Get an optional option - * - * The has_option parameter is set if the option exists and left unmodified if the option does not - * exist. This is provided as a convenience to monitor whether at least one option was set from a - * list of optional options. - * - * @param[in] key option key to look up in options - * @param[out] has_option Set to true if the option exists, unmodified if it does not - * - * @returns value of the option if it exists, an object of type nullopt_t if it does not - */ - template<typename K, typename V> - optional<V> getOptional(K key, const std::map<K,V> &options, bool *has_option) const - { - auto it = options.find(key); + /*! + * Get an optional option + * + * The has_option parameter is set if the option exists and left unmodified if the option does not + * exist. This is provided as a convenience to monitor whether at least one option was set from a + * list of optional options. + * + * @param[in] key option key to look up in options + * @param[out] has_option Set to true if the option exists, unmodified if it does not + * + * @returns value of the option if it exists, an object of type nullopt_t if it does not + */ + template<typename K, typename V> + optional<V> getOptional(K key, const std::map<K,V> &options, bool *has_option) const + { + auto it = options.find(key); - if(it != options.end()) { - if(has_option != nullptr) *has_option = true; - return it->second; - } else { - return cta::nullopt; - } - } + if(it != options.end()) { + if(has_option != nullptr) *has_option = true; + return it->second; + } else { + return cta::nullopt; + } + } - /*! - * Overloaded versions of getOptional - * - * These map the key type to the template specialization of <key,value> pairs - */ - optional<std::string> getOptional(cta::admin::OptionString::Key key, bool *has_option = nullptr) const { - return getOptional(key, m_option_str, has_option); - } - optional<std::vector<std::string>> getOptional(cta::admin::OptionStrList::Key key, bool *has_option = nullptr) const { - return getOptional(key, m_option_str_list, has_option); - } - optional<uint64_t> getOptional(cta::admin::OptionUInt64::Key key, bool *has_option = nullptr) const { - return getOptional(key, m_option_uint64, has_option); - } - optional<bool> getOptional(cta::admin::OptionBoolean::Key key, bool *has_option = nullptr) const { - return getOptional(key, m_option_bool, has_option); - } + /*! + * Overloaded versions of getOptional + * + * These map the key type to the template specialization of <key,value> pairs + */ + optional<std::string> getOptional(cta::admin::OptionString::Key key, bool *has_option = nullptr) const { + return getOptional(key, m_option_str, has_option); + } + optional<std::vector<std::string>> getOptional(cta::admin::OptionStrList::Key key, bool *has_option = nullptr) const { + return getOptional(key, m_option_str_list, has_option); + } + optional<uint64_t> getOptional(cta::admin::OptionUInt64::Key key, bool *has_option = nullptr) const { + return getOptional(key, m_option_uint64, has_option); + } + optional<bool> getOptional(cta::admin::OptionBoolean::Key key, bool *has_option = nullptr) const { + return getOptional(key, m_option_bool, has_option); + } - /*! - * Check if an optional flag has been set - * - * This is a simpler version of getOptional for checking flags which are either present - * or not. In the case of flags, they should always have the value true if the flag is - * present, but we do a redundant check anyway. - * - * @param[in] option Optional command line option - * - * @retval true The flag is present in the options map, and its value is true - * @retval false The flag is either not present or is present and set to false - */ - bool has_flag(cta::admin::OptionBoolean::Key option) const { - auto opt_it = m_option_bool.find(option); - return opt_it != m_option_bool.end() && opt_it->second; - } + /*! + * Check if an optional flag has been set + * + * This is a simpler version of getOptional for checking flags which are either present + * or not. In the case of flags, they should always have the value true if the flag is + * present, but we do a redundant check anyway. + * + * @param[in] option Optional command line option + * + * @retval true The flag is present in the options map, and its value is true + * @retval false The flag is either not present or is present and set to false + */ + bool has_flag(cta::admin::OptionBoolean::Key option) const { + auto opt_it = m_option_bool.find(option); + return opt_it != m_option_bool.end() && opt_it->second; + } private: - /*! - * Process Notification events - * - * @param[in] notification Notification request message from EOS WFE - * @param[out] response Response message to return to EOS - */ - void processOPENW (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Ignore OPENW event - void processCREATE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< New archive file ID event - void processCLOSEW (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Archive file event - void processPREPARE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Retrieve file event - void processABORT_PREPARE(const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Abort retrieve file event - void processDELETE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Delete file event - - /*! - * Process AdminCmd events - * - * @param[out] response CTA Admin command response message - */ - void processAdmin_Add (cta::xrd::Response &response); - void processAdmin_Ch (cta::xrd::Response &response); - void processAdmin_Rm (cta::xrd::Response &response); - void processArchiveRoute_Add (cta::xrd::Response &response); - void processArchiveRoute_Ch (cta::xrd::Response &response); - void processArchiveRoute_Rm (cta::xrd::Response &response); - void processDrive_Up (cta::xrd::Response &response); - void processDrive_Down (cta::xrd::Response &response); - void processDrive_Ls (cta::xrd::Response &response); - void processDrive_Rm (cta::xrd::Response &response); - void processGroupMountRule_Add (cta::xrd::Response &response); - void processGroupMountRule_Ch (cta::xrd::Response &response); - void processGroupMountRule_Rm (cta::xrd::Response &response); - void processGroupMountRule_Ls (cta::xrd::Response &response); - void processLogicalLibrary_Add (cta::xrd::Response &response); - void processLogicalLibrary_Ch (cta::xrd::Response &response); - void processLogicalLibrary_Rm (cta::xrd::Response &response); - void processLogicalLibrary_Ls (cta::xrd::Response &response); - void processMountPolicy_Add (cta::xrd::Response &response); - void processMountPolicy_Ch (cta::xrd::Response &response); - void processMountPolicy_Rm (cta::xrd::Response &response); - void processMountPolicy_Ls (cta::xrd::Response &response); - void processRepack_Add (cta::xrd::Response &response); - void processRepack_Rm (cta::xrd::Response &response); - void processRepack_Err (cta::xrd::Response &response); - void processRequesterMountRule_Add(cta::xrd::Response &response); - void processRequesterMountRule_Ch (cta::xrd::Response &response); - void processRequesterMountRule_Rm (cta::xrd::Response &response); - void processRequesterMountRule_Ls (cta::xrd::Response &response); - void processShowQueues (cta::xrd::Response &response); - void processStorageClass_Add (cta::xrd::Response &response); - void processStorageClass_Ch (cta::xrd::Response &response); - void processStorageClass_Rm (cta::xrd::Response &response); - void processStorageClass_Ls (cta::xrd::Response &response); - void processTape_Add (cta::xrd::Response &response); - void processTape_Ch (cta::xrd::Response &response); - void processTape_Rm (cta::xrd::Response &response); - void processTape_Reclaim (cta::xrd::Response &response); - void processTape_Label (cta::xrd::Response &response); - void processTapePool_Add (cta::xrd::Response &response); - void processTapePool_Ch (cta::xrd::Response &response); - void processTapePool_Rm (cta::xrd::Response &response); - - /*! - * Process AdminCmd events which can return a stream response - * - * @param[out] response Response protocol buffer message. This is used for response - * headers or for summary responses. - * @param[out] stream Reference to Response stream message pointer - */ - typedef void admincmdstream_t(cta::xrd::Response &response, XrdSsiStream* &stream); + /*! + * Process Notification events + * + * @param[in] notification Notification request message from EOS WFE + * @param[out] response Response message to return to EOS + */ + void processOPENW (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Ignore OPENW event + void processCREATE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< New archive file ID event + void processCLOSEW (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Archive file event + void processPREPARE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Retrieve file event + void processABORT_PREPARE(const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Abort retrieve file event + void processDELETE (const cta::eos::Notification ¬ification, cta::xrd::Response &response); //!< Delete file event - admincmdstream_t processAdmin_Ls; - admincmdstream_t processArchiveFile_Ls; - admincmdstream_t processArchiveRoute_Ls; - admincmdstream_t processFailedRequest_Ls; - admincmdstream_t processListPendingArchives; - admincmdstream_t processListPendingRetrieves; - admincmdstream_t processTapePool_Ls; - admincmdstream_t processTape_Ls; - admincmdstream_t processRepack_Ls; + /*! + * Process AdminCmd events + * + * @param[out] response CTA Admin command response message + */ + void processAdmin_Add (cta::xrd::Response &response); + void processAdmin_Ch (cta::xrd::Response &response); + void processAdmin_Rm (cta::xrd::Response &response); + void processArchiveRoute_Add (cta::xrd::Response &response); + void processArchiveRoute_Ch (cta::xrd::Response &response); + void processArchiveRoute_Rm (cta::xrd::Response &response); + void processDrive_Up (cta::xrd::Response &response); + void processDrive_Down (cta::xrd::Response &response); + void processDrive_Rm (cta::xrd::Response &response); + void processGroupMountRule_Add (cta::xrd::Response &response); + void processGroupMountRule_Ch (cta::xrd::Response &response); + void processGroupMountRule_Rm (cta::xrd::Response &response); + void processLogicalLibrary_Add (cta::xrd::Response &response); + void processLogicalLibrary_Ch (cta::xrd::Response &response); + void processLogicalLibrary_Rm (cta::xrd::Response &response); + void processMountPolicy_Add (cta::xrd::Response &response); + void processMountPolicy_Ch (cta::xrd::Response &response); + void processMountPolicy_Rm (cta::xrd::Response &response); + void processRepack_Add (cta::xrd::Response &response); + void processRepack_Rm (cta::xrd::Response &response); + void processRepack_Err (cta::xrd::Response &response); + void processRequesterMountRule_Add(cta::xrd::Response &response); + void processRequesterMountRule_Ch (cta::xrd::Response &response); + void processRequesterMountRule_Rm (cta::xrd::Response &response); + void processStorageClass_Add (cta::xrd::Response &response); + void processStorageClass_Ch (cta::xrd::Response &response); + void processStorageClass_Rm (cta::xrd::Response &response); + void processTape_Add (cta::xrd::Response &response); + void processTape_Ch (cta::xrd::Response &response); + void processTape_Rm (cta::xrd::Response &response); + void processTape_Reclaim (cta::xrd::Response &response); + void processTape_Label (cta::xrd::Response &response); + void processTapePool_Add (cta::xrd::Response &response); + void processTapePool_Ch (cta::xrd::Response &response); + void processTapePool_Rm (cta::xrd::Response &response); - /*! - * Log an admin command - * - * @param[in] admincmd CTA Admin command request message - * @param[in] t CTA Catalogue timer - */ - void logAdminCmd(const std::string &function, const cta::admin::AdminCmd &admincmd, cta::utils::Timer &t); + /*! + * Process AdminCmd events which can return a stream response + * + * @param[out] response Response protocol buffer message. This is used for response + * headers or for summary responses. + * @param[out] stream Reference to Response stream message pointer + */ + typedef void admincmdstream_t(cta::xrd::Response &response, XrdSsiStream* &stream); - /*! - * Drive state enum - */ - enum DriveState { Up, Down }; + admincmdstream_t processAdmin_Ls; + admincmdstream_t processArchiveFile_Ls; + admincmdstream_t processArchiveRoute_Ls; + admincmdstream_t processDrive_Ls; + admincmdstream_t processFailedRequest_Ls; + admincmdstream_t processGroupMountRule_Ls; + admincmdstream_t processListPendingArchives; + admincmdstream_t processListPendingRetrieves; + admincmdstream_t processLogicalLibrary_Ls; + admincmdstream_t processMountPolicy_Ls; + admincmdstream_t processRequesterMountRule_Ls; + admincmdstream_t processShowQueues; + admincmdstream_t processStorageClass_Ls; + admincmdstream_t processTapePool_Ls; + admincmdstream_t processTape_Ls; + admincmdstream_t processRepack_Ls; - /*! - * 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 ®ex, DriveState drive_state); + /*! + * Log an admin command + * + * @param[in] admincmd CTA Admin command request message + * @param[in] t CTA Catalogue timer + */ + void logAdminCmd(const std::string &function, const cta::admin::AdminCmd &admincmd, cta::utils::Timer &t); - /*! - * 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; + /*! + * Drive state enum + */ + enum DriveState { Up, Down }; - /*! - * 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; + /*! + * 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 ®ex, DriveState drive_state); - /*! - * Import Google Protobuf option fields into maps - * - * @param[in] admincmd CTA Admin command request message - */ - void importOptions(const cta::admin::AdminCmd &admincmd); + /*! + * Import Google Protobuf option fields into maps + * + * @param[in] admincmd CTA Admin command request message + */ + void importOptions(const cta::admin::AdminCmd &admincmd); - /*! - * Throw an exception for empty protocol buffer strings - */ - void checkIsNotEmptyString(const std::string &value, const std::string &error_txt) { - if(value.empty()) throw XrdSsiPb::PbException("Protocol buffer field " + error_txt + " is an empty string."); - } + /*! + * Throw an exception for empty protocol buffer strings + */ + void checkIsNotEmptyString(const std::string &value, const std::string &error_txt) { + if(value.empty()) throw XrdSsiPb::PbException("Protocol buffer field " + error_txt + " is an empty string."); + } - // Security protocol used to connect + // Security protocol used to connect - enum class Protocol { SSS, KRB5, OTHER }; + enum class Protocol { SSS, KRB5, OTHER }; - const std::map<std::string, Protocol> m_protomap = { - { "sss", Protocol::SSS }, - { "krb5", Protocol::KRB5 }, - }; + const std::map<std::string, Protocol> m_protomap = { + { "sss", Protocol::SSS }, + { "krb5", Protocol::KRB5 }, + }; - // Member variables + // Member variables - Protocol m_protocol; //!< The protocol the client used to connect - cta::common::dataStructures::SecurityIdentity m_cliIdentity; //!< Client identity: username/host - cta::OStoreDBWithAgent &m_scheddb; //!< Reference to CTA ObjectStore - cta::catalogue::Catalogue &m_catalogue; //!< Reference to CTA Catalogue - cta::Scheduler &m_scheduler; //!< Reference to CTA Scheduler - cta::log::LogContext m_lc; //!< CTA Log Context - std::map<cta::admin::OptionBoolean::Key, bool> m_option_bool; //!< Boolean options - std::map<cta::admin::OptionUInt64::Key, uint64_t> m_option_uint64; //!< UInt64 options - std::map<cta::admin::OptionString::Key, std::string> m_option_str; //!< String options - std::map<cta::admin::OptionStrList::Key, - std::vector<std::string>> m_option_str_list; //!< String List options + Protocol m_protocol; //!< The protocol the client used to connect + cta::common::dataStructures::SecurityIdentity m_cliIdentity; //!< Client identity: username/host + cta::OStoreDBWithAgent &m_scheddb; //!< Reference to CTA ObjectStore + cta::catalogue::Catalogue &m_catalogue; //!< Reference to CTA Catalogue + cta::Scheduler &m_scheduler; //!< Reference to CTA Scheduler + cta::log::LogContext m_lc; //!< CTA Log Context + std::map<cta::admin::OptionBoolean::Key, bool> m_option_bool; //!< Boolean options + std::map<cta::admin::OptionUInt64::Key, uint64_t> m_option_uint64; //!< UInt64 options + std::map<cta::admin::OptionString::Key, std::string> m_option_str; //!< String options + std::map<cta::admin::OptionStrList::Key, + std::vector<std::string>> m_option_str_list; //!< String List options }; }} // namespace cta::xrd diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface index 17f1f77acc76a15bd9f494cfd65bdab68ee8ac19..602063b47e056ae84b45726fad63162ad6d6975b 160000 --- a/xrootd-ssi-protobuf-interface +++ b/xrootd-ssi-protobuf-interface @@ -1 +1 @@ -Subproject commit 17f1f77acc76a15bd9f494cfd65bdab68ee8ac19 +Subproject commit 602063b47e056ae84b45726fad63162ad6d6975b