diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index d341ae5fad80d2e935e32d8d806476d1f2fec22f..e6029f801aef5c08a3e1f56a6de61994bdda981e 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -343,7 +343,8 @@ const std::map<std::string, OptionString::Key> strOptions = { {"--guiurl", OptionString::GUI_URL }, {"--webcamurl", OptionString::WEBCAM_URL }, {"--location", OptionString::LIBRARY_LOCATION }, - {"--archiveroutetype", OptionString::ARCHIVE_ROUTE_TYPE } + {"--archiveroutetype", OptionString::ARCHIVE_ROUTE_TYPE }, + {"--diskfileid", OptionString::DISK_FILE_ID } }; /*! @@ -401,6 +402,7 @@ const Option opt_drivename_cmd {Option::OPT_CMD, "--drive", "", "<drive_name>"}; const Option opt_encrypted {Option::OPT_BOOL, "--encrypted", "-e", R"( <"true" or "false">)"}; const Option opt_encryptionkeyname {Option::OPT_STR, "--encryptionkeyname", "-k", " <encryption_key_name>"}; const Option opt_fid {Option::OPT_STR, "--fxid", "-f", " <eos_fxid>"}; +const Option opt_diskfileid {Option::OPT_STR, "--diskfileid", "--dfid", " <disk_file_id>"}; const Option opt_fidfile {Option::OPT_STR_LIST, "--fxidfile", "-F", " <filename>"}; const Option opt_filename {Option::OPT_STR, "--file", "-f", " <filename>"}; const Option opt_force {Option::OPT_BOOL, "--force", "-f", R"( <"true" or "false">)"}; @@ -883,6 +885,7 @@ recycletf (rtf) {{AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_LS}, {opt_vid.optional(), opt_fid.optional(), + opt_diskfileid.optional(), opt_fidfile.optional(), opt_copynb.optional(), opt_archivefileid.optional(), @@ -1060,10 +1063,11 @@ tapefile (tf) {opt_vid.optional(), opt_instance.optional(), opt_fid.optional(), + opt_diskfileid.optional(), opt_fidfile.optional(), opt_archivefileid.optional()} }, {{AdminCmd::CMD_TAPEFILE, AdminCmd::SUBCMD_RM}, - {opt_vid, opt_instance.optional(), opt_fid.optional(), opt_archivefileid.optional(), opt_reason} }, + {opt_vid, opt_instance.optional(), opt_fid.optional(), opt_diskfileid.optional(), opt_archivefileid.optional(), opt_reason} }, /**md tapepool (tp) @@ -1151,10 +1155,10 @@ virtualorganization (vo) // Used by cta-change-storageclass and cta-eos-namespace-inject {{AdminCmd::CMD_ARCHIVEFILE, AdminCmd::SUBCMD_CH}, - {opt_storageclass.optional(), opt_archive_file_ids, opt_fid.optional(), opt_diskinstance.optional()} }, + {opt_storageclass.optional(), opt_archive_file_ids, opt_fid.optional(), opt_diskfileid.optional(), opt_diskinstance.optional()} }, // Used by cta-restore-deleted-files {{AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_RESTORE}, - {opt_vid.optional(), opt_fid, opt_copynb.optional(), opt_archivefileid.optional(), opt_instance.optional()} }, + {opt_vid.optional(), opt_fid.optional(), opt_diskfileid.optional(), opt_copynb.optional(), opt_archivefileid.optional(), opt_instance.optional()} }, /*-------------------------------------------------------------------------------------------------------------------------*/ }; diff --git a/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.cpp b/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.cpp index a31d8b56ca20dd9f692b89672df8afb7725e9975..4d09c8dc4cadd4922c80794d6e9b852fad01d764 100644 --- a/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.cpp +++ b/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.cpp @@ -76,7 +76,7 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const { g_metaDataObjectCatalogue.size = std::to_string(item.af().size()); g_metaDataObjectCatalogue.storageClass = item.af().storage_class(); g_metaDataObjectCatalogue.creationTime = std::to_string(item.af().creation_time()); - g_metaDataObjectCatalogue.fxId = item.df().disk_id(); + g_metaDataObjectCatalogue.diskFileId = item.df().disk_id(); g_metaDataObjectCatalogue.diskInstance = item.df().disk_instance(); std::string checksumType("NONE"); @@ -152,10 +152,10 @@ int EosNamespaceInjection::exceptionThrowingMain(const int argc, char *const *co const auto newFid = createFileInEos(metaDataFromUser, parentId, uid, gid); checkFileCreated(newFid); - std::string newFxId = cta::utils::decimalToHexadecimal(std::to_string(newFid)); - updateFxidAndDiskInstanceInCatalogue(metaDataFromUser.archiveId, newFxId, metaDataFromUser.diskInstance); + auto diskFileId = std::to_string(newFid); + updateDiskFileIdAndDiskInstanceInCatalogue(metaDataFromUser.archiveId, diskFileId, metaDataFromUser.diskInstance); - checkEosCtaConsistency(archiveId, newFxId, metaDataFromUser); + checkEosCtaConsistency(archiveId, diskFileId, metaDataFromUser); } createTxtFileWithSkippedMetadata(); return 0; @@ -164,7 +164,7 @@ int EosNamespaceInjection::exceptionThrowingMain(const int argc, char *const *co //------------------------------------------------------------------------------ // updateFxidAndDiskInstanceInCatalogue //------------------------------------------------------------------------------ -void EosNamespaceInjection::updateFxidAndDiskInstanceInCatalogue(const std::string &archiveId, const std::string &fxId, const std::string &diskInstance) const { +void EosNamespaceInjection::updateDiskFileIdAndDiskInstanceInCatalogue(const std::string &archiveId, const std::string &diskFileId, const std::string &diskInstance) const { cta::xrd::Request request; const auto admincmd = request.mutable_admincmd(); @@ -175,21 +175,21 @@ void EosNamespaceInjection::updateFxidAndDiskInstanceInCatalogue(const std::stri admincmd->set_subcmd(cta::admin::AdminCmd::SUBCMD_CH); { - const auto key = cta::admin::OptionString::FXID; + constexpr auto key = cta::admin::OptionString::DISK_FILE_ID; const auto new_opt = admincmd->add_option_str(); new_opt->set_key(key); - new_opt->set_value(fxId); + new_opt->set_value(diskFileId); } { - const auto key = cta::admin::OptionString::DISK_INSTANCE; + constexpr auto key = cta::admin::OptionString::DISK_INSTANCE; const auto new_opt = admincmd->add_option_str(); new_opt->set_key(key); new_opt->set_value(diskInstance); } { - const auto key = cta::admin::OptionStrList::FILE_ID; + constexpr auto key = cta::admin::OptionStrList::FILE_ID; const auto new_opt = admincmd->add_option_str_list(); new_opt->set_key(key); new_opt->add_item(archiveId); @@ -379,14 +379,15 @@ uint64_t EosNamespaceInjection::createFileInEos(const MetaDataObject &metaDataFr // getArchiveFileIdFromEOS //------------------------------------------------------------------------------ std::pair<ArchiveId, Checksum> EosNamespaceInjection::getArchiveFileIdAndChecksumFromEOS( - const std::string& diskInstance, const std::string& fxId) { - auto fid = strtoul(fxId.c_str(), nullptr, 10); + const std::string& diskInstance, const std::string& diskFileId) const { + const auto fid = strtoul(diskFileId.c_str(), nullptr, 10); if(fid < 1) { - throw std::runtime_error(fid + " (base 10) is not a valid disk file ID"); + throw std::runtime_error(diskFileId + " is not a valid EOS base-10 disk file ID"); } { std::list<cta::log::Param> params; params.push_back(cta::log::Param("diskInstance", diskInstance)); + params.push_back(cta::log::Param("diskFileId", diskFileId)); params.push_back(cta::log::Param("fid", fid)); std::stringstream ss; ss << std::hex << fid; @@ -436,18 +437,18 @@ void EosNamespaceInjection::setCmdLineArguments(const int argc, char *const *con //------------------------------------------------------------------------------ // checkEosCtaConsistency //------------------------------------------------------------------------------ -bool EosNamespaceInjection::checkEosCtaConsistency(const uint64_t& archiveId, const std::string& newFxIdEos, const MetaDataObject &metaDataFromUser) { +bool EosNamespaceInjection::checkEosCtaConsistency(const uint64_t& archiveId, const std::string& newDiskFileId, const MetaDataObject &metaDataFromUser) { getMetaDataFromCatalogue(archiveId); - const auto [eosArchiveFileId, eosChecksumDecimal] = getArchiveFileIdAndChecksumFromEOS(metaDataFromUser.diskInstance, newFxIdEos); + const auto [eosArchiveFileId, eosChecksumDecimal] = getArchiveFileIdAndChecksumFromEOS(metaDataFromUser.diskInstance, newDiskFileId); const std::string eosChecksum = cta::utils::decimalToHexadecimal(eosChecksumDecimal); const auto& ctaChecksum = g_metaDataObjectCatalogue.checksumValue; std::list<cta::log::Param> params; params.push_back(cta::log::Param("archiveFileId", archiveId)); - params.push_back(cta::log::Param("diskFileId in EOS for new file", newFxIdEos)); - params.push_back(cta::log::Param("diskFileId in Catalogue", g_metaDataObjectCatalogue.fxId)); + params.push_back(cta::log::Param("diskFileId in EOS for new file", newDiskFileId)); + params.push_back(cta::log::Param("diskFileId in Catalogue", g_metaDataObjectCatalogue.diskFileId)); params.push_back(cta::log::Param("diskInstance in Catalogue", g_metaDataObjectCatalogue.diskInstance)); params.push_back(cta::log::Param("checksum", ctaChecksum)); - if(eosArchiveFileId == archiveId && eosChecksum == ctaChecksum && g_metaDataObjectCatalogue.fxId == newFxIdEos) { + if(eosArchiveFileId == archiveId && eosChecksum == ctaChecksum && g_metaDataObjectCatalogue.diskFileId == newDiskFileId) { m_log(cta::log::INFO, "File metadata in EOS and CTA matches", params); return true; } else { @@ -503,8 +504,7 @@ void EosNamespaceInjection::checkArchiveIdExistsInCatalogue(const uint64_t &arch // checkExistingPathHasInvalidMetadata //------------------------------------------------------------------------------ void EosNamespaceInjection::checkExistingPathHasInvalidMetadata(const uint64_t &archiveId, const uint64_t& fid, const MetaDataObject& metaDataFromUser) { - const std::string fxId = cta::utils::decimalToHexadecimal(std::to_string(fid)); - if(!checkEosCtaConsistency(archiveId, fxId, metaDataFromUser)) { + if(!checkEosCtaConsistency(archiveId, std::to_string(fid), metaDataFromUser)) { throw cta::cliTool::EosNameSpaceInjectionError("The file with path " + metaDataFromUser.eosPath + " already exists for instance " + metaDataFromUser.diskInstance + ". This tool does not overwrite existing files"); } } diff --git a/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.hpp b/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.hpp index 1dca6860fa61e39deaced13a7bdbfbdf9c3d1557..7d014d6ef74b711a0669bba9752fb9fa99778196 100644 --- a/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.hpp +++ b/cmdline/standalone_cli_tools/eos_namespace_injection/EosNamespaceInjection.hpp @@ -74,12 +74,12 @@ class EosNamespaceInjection final: public CmdLineTool { bool getMetaDataFromCatalogue(const uint64_t &archiveId) const; /** - * Updates the fxid and the disk instance in the catalogue. + * Updates the disk file ID and the disk instance in the catalogue. * @param archiveId the archive file id to check - * @param fxId The new fxId - * @param diskInstnace The new disk instance + * @param diskFileId The new diskFileID + * @param diskInstance The new disk instance */ - void updateFxidAndDiskInstanceInCatalogue(const std::string &archiveId, const std::string &fxId, const std::string &diskInstance) const; + void updateDiskFileIdAndDiskInstanceInCatalogue(const std::string &archiveId, const std::string &diskFileId, const std::string &diskInstance) const; /** * Compares the meta data from the provided json and from the Catalogue @@ -113,9 +113,9 @@ class EosNamespaceInjection final: public CmdLineTool { /** * Gets the archive file id and checksum from eos * @param diskInstance The eos disk instance - * @param fxId The eos file id + * @param diskFileId The eos disk file id */ - std::pair<ArchiveId, Checksum> getArchiveFileIdAndChecksumFromEOS(const std::string& diskInstance, const std::string& fxId); + std::pair<ArchiveId, Checksum> getArchiveFileIdAndChecksumFromEOS(const std::string& diskInstance, const std::string& diskFileId) const; /** * Validates the command line arguments diff --git a/cmdline/standalone_cli_tools/eos_namespace_injection/MetaData.hpp b/cmdline/standalone_cli_tools/eos_namespace_injection/MetaData.hpp index 4f89ecc684bc9cc4d9ccda19da4c2342be304a69..0dd2867afbdc976bcda4797a7b45aa8f16a6bbf0 100644 --- a/cmdline/standalone_cli_tools/eos_namespace_injection/MetaData.hpp +++ b/cmdline/standalone_cli_tools/eos_namespace_injection/MetaData.hpp @@ -28,7 +28,7 @@ namespace cta::cliTool { struct MetaDataObject { std::string eosPath; std::string diskInstance; - std::string fxId; + std::string diskFileId; std::string creationTime; std::string archiveId; std::string size; diff --git a/cmdline/standalone_cli_tools/restore_files/RestoreFilesCmd.cpp b/cmdline/standalone_cli_tools/restore_files/RestoreFilesCmd.cpp index 519254c3c8f7ac205621b6f896e86f954695cd7b..c14dcc2117431b6bfbc78e7acb1db9e3c882d941 100644 --- a/cmdline/standalone_cli_tools/restore_files/RestoreFilesCmd.cpp +++ b/cmdline/standalone_cli_tools/restore_files/RestoreFilesCmd.cpp @@ -317,37 +317,36 @@ void RestoreFilesCmd::restoreDeletedFileCopyCta(const cta::admin::RecycleTapeFil admincmd.set_subcmd(cta::admin::AdminCmd::SUBCMD_RESTORE); { - auto key = cta::admin::OptionString::VID; - auto new_opt = admincmd.add_option_str(); + constexpr auto key = cta::admin::OptionString::VID; + const auto new_opt = admincmd.add_option_str(); new_opt->set_key(key); new_opt->set_value(file.vid()); } { - auto key = cta::admin::OptionString::INSTANCE; - auto new_opt = admincmd.add_option_str(); + constexpr auto key = cta::admin::OptionString::INSTANCE; + const auto new_opt = admincmd.add_option_str(); new_opt->set_key(key); new_opt->set_value(file.disk_instance()); } { - auto key = cta::admin::OptionUInt64::ARCHIVE_FILE_ID; - auto new_opt = admincmd.add_option_uint64(); + constexpr auto key = cta::admin::OptionUInt64::ARCHIVE_FILE_ID; + const auto new_opt = admincmd.add_option_uint64(); new_opt->set_key(key); new_opt->set_value(file.archive_file_id()); } { - auto key = cta::admin::OptionUInt64::COPY_NUMBER; - auto new_opt = admincmd.add_option_uint64(); + constexpr auto key = cta::admin::OptionUInt64::COPY_NUMBER; + const auto new_opt = admincmd.add_option_uint64(); new_opt->set_key(key); new_opt->set_value(file.copy_nb()); } { - auto key = cta::admin::OptionString::FXID; - auto new_opt = admincmd.add_option_str(); + constexpr auto key = cta::admin::OptionString::DISK_FILE_ID; + const auto new_opt = admincmd.add_option_str(); - if (!utils::isValidID(file.disk_file_id())) { + if (!utils::isValidDecimal(file.disk_file_id()) && !utils::isValidUUID(file.disk_file_id())) { throw std::runtime_error(file.disk_file_id() + " is not a valid disk file ID"); } - params.emplace_back("fid", file.disk_file_id()); new_opt->set_key(key); new_opt->set_value(file.disk_file_id()); } diff --git a/common/utils/utils.cpp b/common/utils/utils.cpp index 7166019754f2127e8292d15ac4a5e00a43144a34..4bf6e5e1d801eef1c0e7a150b8d0d1fe6aab8ab3 100644 --- a/common/utils/utils.cpp +++ b/common/utils/utils.cpp @@ -998,10 +998,18 @@ std::string listToCommaSeparatedString(const std::list<std::string>& list) { return oss.str(); } -std::string decimalToHexadecimal(const std::string& decimalNumber) { - std::stringstream fxIdStream; - fxIdStream << std::hex << decimalNumber; - return fxIdStream.str(); +std::string decimalToHexadecimal(const std::string& decimalNumberStr) { + std::stringstream fxidStream; + const auto decimalNumber = stol(decimalNumberStr); + fxidStream << std::hex << decimalNumber; + return fxidStream.str(); +} + +std::string hexadecimalToDecimal(const std::string& hexadecimalNumberStr) { + std::stringstream fidStream; + const auto decimalNumber = stol(hexadecimalNumberStr, nullptr, 16); + fidStream << std::dec << decimalNumber; + return fidStream.str(); } // Check if uuid is correct diff --git a/common/utils/utils.hpp b/common/utils/utils.hpp index 4a1ed99f520ad80e8c6d9e25534a60bdd9c3c7dc..6860f947e9db7314c1569980402a819c2916bfcf 100644 --- a/common/utils/utils.hpp +++ b/common/utils/utils.hpp @@ -501,11 +501,18 @@ std::list<std::string> commaSeparatedStringToList(const std::string& commaSepara std::string listToCommaSeparatedString(const std::list<std::string>& list); /** - * Converts a number from a decimal number to a hexidecimal number - * @param decimalNumber The number that will be transformed - * @return the hexadecimal version of the number + * Converts a number from decimal to hexadecimal representation + * @param decimalNumberStr String containing the decimal number that will be transformed + * @return the hexadecimal representation of the number */ -std::string decimalToHexadecimal(const std::string& decimalNumber); +std::string decimalToHexadecimal(const std::string& decimalNumberStr); + +/** + * Converts a number from hexadecimal to decimal representation + * @param hexadecimalNumberStr String containing the hexadecimal number that will be transformed + * @return the decimal representation of the number + */ +std::string hexadecimalToDecimal(const std::string& hexadecimalNumberStr); /** * Checks if a string is a valid UUID. diff --git a/frontend/common/AdminCmd.cpp b/frontend/common/AdminCmd.cpp index 3033b5e7beeaca502702a75099300eb92a69ac85..79d0402fcb440b5fdddde0f7bd655149f1434eab 100644 --- a/frontend/common/AdminCmd.cpp +++ b/frontend/common/AdminCmd.cpp @@ -1195,7 +1195,7 @@ void AdminCmd::processTapeFile_Rm(xrd::Response& response) { auto& reason = getRequired(OptionString::REASON); auto archiveFileId = getOptional(OptionUInt64::ARCHIVE_FILE_ID); auto instance = getOptional(OptionString::INSTANCE); - auto diskFileId = getOptional(OptionString::FXID); + auto diskFileIdStr = getAndValidateDiskFileIdOptional(); catalogue::TapeFileSearchCriteria searchCriteria; searchCriteria.vid = vid; @@ -1203,14 +1203,12 @@ void AdminCmd::processTapeFile_Rm(xrd::Response& response) { if(archiveFileId) { searchCriteria.archiveFileId = archiveFileId.value(); } - if(diskFileId) { - auto fid = strtol(diskFileId.value().c_str(), nullptr, 16); - if(fid < 1 || fid == LONG_MAX) { - throw exception::UserError(diskFileId.value() + " is not a valid file ID"); - } + + if(diskFileIdStr) { searchCriteria.diskFileIds = std::vector<std::string>(); - searchCriteria.diskFileIds.value().push_back(std::to_string(fid)); + searchCriteria.diskFileIds.value().push_back(diskFileIdStr.value()); } + if(instance) { searchCriteria.diskInstance = instance.value(); } @@ -1591,6 +1589,33 @@ std::string AdminCmd::setDriveState(const std::string& regex, const common::data return cmdlineOutput.str(); } +std::optional<std::string> AdminCmd::getAndValidateDiskFileIdOptional(bool* has_any) const { + using namespace cta::admin; + auto diskFileIdHex = getOptional(OptionString::FXID, has_any); + auto diskFileIdStr = getOptional(OptionString::DISK_FILE_ID, has_any); + + if(diskFileIdHex && diskFileIdStr) { + throw exception::UserError("File ID can't be received in both string (" + diskFileIdStr.value() + ") and hexadecimal (" + diskFileIdHex.value() + ") formats"); + } + + if(diskFileIdHex) { + // If provided, convert FXID (hexadecimal) to DISK_FILE_ID (decimal) + if (!utils::isValidHex(diskFileIdHex.value())) { + throw cta::exception::UserError(diskFileIdHex.value() + " is not a valid hexadecimal file ID value"); + } + return utils::hexadecimalToDecimal(diskFileIdHex.value()); + } + + if(diskFileIdStr) { + if (!utils::isValidDecimal(diskFileIdStr.value()) && !utils::isValidUUID(diskFileIdStr.value())) { + throw cta::exception::UserError(diskFileIdStr.value() + " is not a valid decimal or UUID file ID value"); + } + return diskFileIdStr; + } + + return std::nullopt; +} + void AdminCmd::processRecycleTapeFile_Restore(xrd::Response& response) { using namespace cta::admin; @@ -1600,11 +1625,10 @@ void AdminCmd::processRecycleTapeFile_Restore(xrd::Response& response) { catalogue::RecycleTapeFileSearchCriteria searchCriteria; searchCriteria.vid = getOptional(OptionString::VID, &has_any); - auto diskFileId = getRequired(OptionString::FXID); - - auto fid = strtol(diskFileId.c_str(), nullptr, 16); - if(fid < 1 || fid == LONG_MAX) { - throw exception::UserError(diskFileId + " is not a valid file ID"); + + const auto diskFileIdStr = getAndValidateDiskFileIdOptional(); + if(!diskFileIdStr) { + throw exception::UserError("Must specify at least one of the following search options: fxid, diskfileid"); } // Disk instance on its own does not give a valid set of search criteria (no &has_any) @@ -1616,7 +1640,7 @@ void AdminCmd::processRecycleTapeFile_Restore(xrd::Response& response) { if(!has_any) { throw exception::UserError("Must specify at least one of the following search options: vid, fxid, fxidfile or archiveFileId"); } - m_catalogue.FileRecycleLog()->restoreFileInRecycleLog(searchCriteria, std::to_string(fid)); + m_catalogue.FileRecycleLog()->restoreFileInRecycleLog(searchCriteria, diskFileIdStr.value()); response.set_type(xrd::Response::RSP_SUCCESS); } @@ -1625,7 +1649,8 @@ void AdminCmd::processModifyArchiveFile(xrd::Response& response) { try { std::optional<std::string> newStorageClassName = getOptional(OptionString::STORAGE_CLASS); - std::optional<std::string> fxId = getOptional(OptionString::FXID); + + std::optional<std::string> diskFileIdStr = getAndValidateDiskFileIdOptional(); std::optional<std::string> diskInstance = getOptional(OptionString::DISK_INSTANCE); auto archiveFileIds = getRequired(OptionStrList::FILE_ID); @@ -1638,9 +1663,9 @@ void AdminCmd::processModifyArchiveFile(xrd::Response& response) { } } // call is from cta-eos-namespace-inject - else if(fxId && diskInstance) { + else if(diskFileIdStr && diskInstance) { m_catalogue.ArchiveFile()->modifyArchiveFileFxIdAndDiskInstance(utils::toUint64(archiveFileIds[0]), - fxId.value(), diskInstance.value()); + diskFileIdStr.value(), diskInstance.value()); } else { throw exception::UserError("Must specify either Storage Class or Disk File ID and Disk Instance"); } diff --git a/frontend/common/AdminCmd.hpp b/frontend/common/AdminCmd.hpp index 6e0124f42fefef66912a6589e687c74d096b3d1a..cdacf4fd4d357e6a6580baa05e0786c2231c7c34 100644 --- a/frontend/common/AdminCmd.hpp +++ b/frontend/common/AdminCmd.hpp @@ -112,6 +112,19 @@ public: return opt_it != m_option_bool.end() && opt_it->second; } + /*! + * Both parameters FXID and DISK_FILE_ID expect the same information but with different formats. + * They can't both be set simultaneously, to avoid inconsistencies. + * + * This function tries to parse one of these values and return it as a string (integer or UUID). + * + * @throws UserError if both FXID and DISK_FILE_ID are defined + * @throws UserError if format of FXID or DISK_FILE_ID is wrong + * + * @return The disk file ID as a string (integer or UUID), or nullopt if none defined. + */ + std::optional<std::string> getAndValidateDiskFileIdOptional(bool* has_any = nullptr) const; + protected: /*! * Convert AdminCmd <Cmd, SubCmd> pair to an integer so that it can be used in a switch statement diff --git a/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp b/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp index 39d4d7e06c8666cf08bef85599e488ba664a70bc..3d9c560d7398cd6008e0e6cc994f364936a940d9 100644 --- a/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp +++ b/xroot_plugins/XrdCtaRecycleTapeFileLs.hpp @@ -68,18 +68,12 @@ RecycleTapeFileLsStream::RecycleTapeFileLsStream(const frontend::AdminCmdStream& searchCriteria.vid = requestMsg.getOptional(OptionString::VID, &has_any); - auto diskFileId = requestMsg.getOptional(OptionString::FXID, &has_any); + auto diskFileIdStr = requestMsg.getAndValidateDiskFileIdOptional(&has_any); searchCriteria.diskFileIds = requestMsg.getOptional(OptionStrList::FILE_ID, &has_any); - - if (diskFileId){ - if (auto fid = diskFileId.value(); !utils::isValidID(fid)) { - throw cta::exception::UserError(fid + " is not a valid file ID"); - } - - // single option on the command line we need to do the conversion ourselves. + if (diskFileIdStr){ if(!searchCriteria.diskFileIds) searchCriteria.diskFileIds = std::vector<std::string>(); - searchCriteria.diskFileIds->push_back(diskFileId.value()); + searchCriteria.diskFileIds->push_back(diskFileIdStr.value()); } searchCriteria.diskInstance = requestMsg.getOptional(OptionString::INSTANCE, &has_any); searchCriteria.archiveFileId = requestMsg.getOptional(OptionUInt64::ARCHIVE_FILE_ID, &has_any); diff --git a/xroot_plugins/XrdCtaTapeFileLs.hpp b/xroot_plugins/XrdCtaTapeFileLs.hpp index 5c438b552ba4b928eebb51fe5f9cf2665758e335..d19810387d62d49d2e3667ac0fb46f7c27907a98 100644 --- a/xroot_plugins/XrdCtaTapeFileLs.hpp +++ b/xroot_plugins/XrdCtaTapeFileLs.hpp @@ -64,22 +64,20 @@ TapeFileLsStream::TapeFileLsStream(const frontend::AdminCmdStream& requestMsg, cta::catalogue::TapeFileSearchCriteria searchCriteria; searchCriteria.vid = requestMsg.getOptional(OptionString::VID, &has_any); + auto diskFileIdStr = requestMsg.getAndValidateDiskFileIdOptional(&has_any); + // Disk file IDs can be a list or a single ID - auto diskFileId = requestMsg.getOptional(OptionString::FXID, &has_any); searchCriteria.diskFileIds = requestMsg.getOptional(OptionStrList::FILE_ID, &has_any); - if(diskFileId.has_value()) { - if (auto fid = diskFileId.value(); !utils::isValidID(fid)) { - throw cta::exception::UserError(fid + " is not a valid file ID"); - } + if(diskFileIdStr) { if(!searchCriteria.diskFileIds) searchCriteria.diskFileIds = std::vector<std::string>(); - searchCriteria.diskFileIds->push_back(diskFileId.value()); + searchCriteria.diskFileIds->push_back(diskFileIdStr.value()); } searchCriteria.diskInstance = requestMsg.getOptional(OptionString::INSTANCE, &has_any); searchCriteria.archiveFileId = requestMsg.getOptional(OptionUInt64::ARCHIVE_FILE_ID, &has_any); if(!has_any) { - throw cta::exception::UserError("Must specify at least one of the following search options: vid, fxid, fxidfile or archiveFileId"); + throw cta::exception::UserError("Must specify at least one of the following search options: vid, fxid, diskfileid, fxidfile or archiveFileId"); } m_tapeFileItor = m_catalogue.ArchiveFile()->getArchiveFilesItor(searchCriteria); diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface index d3ab3e9ee657c9a0f67a9f2cc168cd9d7b6b7bf9..95ca6aca153a6e72a33a281258e3372d54fe6a74 160000 --- a/xrootd-ssi-protobuf-interface +++ b/xrootd-ssi-protobuf-interface @@ -1 +1 @@ -Subproject commit d3ab3e9ee657c9a0f67a9f2cc168cd9d7b6b7bf9 +Subproject commit 95ca6aca153a6e72a33a281258e3372d54fe6a74