diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 7dffa6b371f445b880480a546508ff61ea27fa5f..94efb5edd7de0897fea2010e97440751e19b6fa1 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -70,6 +70,7 @@ #include "disk/DiskSystem.hpp" #include "RecyleTapeFileSearchCriteria.hpp" #include "CreateMountPolicyAttributes.hpp" +#include "TapePoolSearchCriteria.hpp" #include <list> #include <map> @@ -92,6 +93,7 @@ CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentArchiveRoute); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentLogicalLibrary); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentTape); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentTapePool); +CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentVirtualOrganization); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedAnEmptyStringComment); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedAnEmptyStringDiskSystemName); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedAnEmptyStringFileRegexp); @@ -488,7 +490,7 @@ public: */ virtual void deleteTapePool(const std::string &name) = 0; - virtual std::list<TapePool> getTapePools() const = 0; + virtual std::list<TapePool> getTapePools(const TapePoolSearchCriteria &searchCriteria = TapePoolSearchCriteria()) const = 0; /** * @return The tape pool with the specified name. diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index 506d475b23bb61d4b36c6496657ada9b15b0d666..2e1ffa70f7dd93638aaf347ca33aa84d4d982dad 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -241,8 +241,8 @@ public: return retryOnLostConnection(m_log, [&]{return m_catalogue->deleteTapePool(name);}, m_maxTriesToConnect); } - std::list<TapePool> getTapePools() const override { - return retryOnLostConnection(m_log, [&]{return m_catalogue->getTapePools();}, m_maxTriesToConnect); + std::list<TapePool> getTapePools(const TapePoolSearchCriteria &searchCriteria) const override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->getTapePools(searchCriteria);}, m_maxTriesToConnect); } cta::optional<TapePool> getTapePool(const std::string &tapePoolName) const override { diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index ba7ddf2326d9126f8403532f975cf5e4053de901..cd94aa12cd9d0b993910c85acae531b1b2416907 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -2942,6 +2942,250 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_nonExistentTapePool) { ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, supply), exception::UserError); } +TEST_P(cta_catalogue_CatalogueTest, getTapePools_filterName) { + using namespace cta; + + const std::string tapePoolName = "tape_pool"; + const std::string secondTapePoolName = "tape_pool_2"; + + const uint64_t nbFirstPoolPartialTapes = 2; + const uint64_t nbSecondPoolPartialTapes = 3; + + const bool firstPoolIsEncrypted = true; + const bool secondPoolIsEncrypted = false; + + const cta::optional<std::string> firstPoolSupply("value for the supply first pool mechanism"); + const cta::optional<std::string> secondPoolSupply("value for the supply second pool mechanism"); + + const std::string firstPoolComment = "Create first tape pool"; + const std::string secondPoolComment = "Create second tape pool"; + + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createVirtualOrganization(m_admin, m_anotherVo); + + m_catalogue->createTapePool(m_admin, tapePoolName, m_vo.name, nbFirstPoolPartialTapes, firstPoolIsEncrypted, firstPoolSupply, firstPoolComment); + m_catalogue->createTapePool(m_admin, secondTapePoolName, m_anotherVo.name, nbSecondPoolPartialTapes, secondPoolIsEncrypted, secondPoolSupply, secondPoolComment); + + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.name = tapePoolName; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(tapePoolName, pool.name); + ASSERT_EQ(m_vo.name, pool.vo.name); + ASSERT_EQ(nbFirstPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(firstPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(firstPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.name = secondTapePoolName; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(secondTapePoolName, pool.name); + ASSERT_EQ(m_anotherVo.name, pool.vo.name); + ASSERT_EQ(nbSecondPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(secondPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(secondPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.name = "no pool with such name"; + + ASSERT_THROW(m_catalogue->getTapePools(criteria), catalogue::UserSpecifiedANonExistentTapePool); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.name = ""; + + ASSERT_THROW(m_catalogue->getTapePools(criteria), exception::UserError); + } +} + +TEST_P(cta_catalogue_CatalogueTest, getTapePools_filterVO) { + using namespace cta; + + const std::string tapePoolName = "tape_pool"; + const std::string secondTapePoolName = "tape_pool_2"; + + const uint64_t nbFirstPoolPartialTapes = 2; + const uint64_t nbSecondPoolPartialTapes = 3; + + const bool firstPoolIsEncrypted = true; + const bool secondPoolIsEncrypted = false; + + const cta::optional<std::string> firstPoolSupply("value for the supply first pool mechanism"); + const cta::optional<std::string> secondPoolSupply("value for the supply second pool mechanism"); + + const std::string firstPoolComment = "Create first tape pool"; + const std::string secondPoolComment = "Create second tape pool"; + + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createVirtualOrganization(m_admin, m_anotherVo); + + m_catalogue->createTapePool(m_admin, tapePoolName, m_vo.name, nbFirstPoolPartialTapes, firstPoolIsEncrypted, firstPoolSupply, firstPoolComment); + m_catalogue->createTapePool(m_admin, secondTapePoolName, m_anotherVo.name, nbSecondPoolPartialTapes, secondPoolIsEncrypted, secondPoolSupply, secondPoolComment); + + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.vo = m_vo.name; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(tapePoolName, pool.name); + ASSERT_EQ(m_vo.name, pool.vo.name); + ASSERT_EQ(nbFirstPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(firstPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(firstPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.vo = m_anotherVo.name; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(secondTapePoolName, pool.name); + ASSERT_EQ(m_anotherVo.name, pool.vo.name); + ASSERT_EQ(nbSecondPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(secondPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(secondPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.vo = "no vo with such name"; + + ASSERT_THROW(m_catalogue->getTapePools(criteria), catalogue::UserSpecifiedANonExistentVirtualOrganization); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.vo = ""; + + ASSERT_THROW(m_catalogue->getTapePools(criteria), exception::UserError); + } +} + +TEST_P(cta_catalogue_CatalogueTest, getTapePools_filterEncrypted) { + using namespace cta; + + const std::string tapePoolName = "tape_pool"; + const std::string secondTapePoolName = "tape_pool_2"; + + const uint64_t nbFirstPoolPartialTapes = 2; + const uint64_t nbSecondPoolPartialTapes = 3; + + const bool firstPoolIsEncrypted = true; + const bool secondPoolIsEncrypted = false; + + const cta::optional<std::string> firstPoolSupply("value for the supply first pool mechanism"); + const cta::optional<std::string> secondPoolSupply("value for the supply second pool mechanism"); + + const std::string firstPoolComment = "Create first tape pool"; + const std::string secondPoolComment = "Create second tape pool"; + + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createVirtualOrganization(m_admin, m_anotherVo); + + m_catalogue->createTapePool(m_admin, tapePoolName, m_vo.name, nbFirstPoolPartialTapes, firstPoolIsEncrypted, firstPoolSupply, firstPoolComment); + m_catalogue->createTapePool(m_admin, secondTapePoolName, m_anotherVo.name, nbSecondPoolPartialTapes, secondPoolIsEncrypted, secondPoolSupply, secondPoolComment); + + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.encrypted = true; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(tapePoolName, pool.name); + ASSERT_EQ(m_vo.name, pool.vo.name); + ASSERT_EQ(nbFirstPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(firstPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(firstPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } + + { + cta::catalogue::TapePoolSearchCriteria criteria; + criteria.encrypted = false; + const auto pools = m_catalogue->getTapePools(criteria); + ASSERT_EQ(1, pools.size()); + + const auto &pool = pools.front(); + ASSERT_EQ(secondTapePoolName, pool.name); + ASSERT_EQ(m_anotherVo.name, pool.vo.name); + ASSERT_EQ(nbSecondPoolPartialTapes, pool.nbPartialTapes); + ASSERT_EQ(secondPoolIsEncrypted, pool.encryption); + ASSERT_TRUE((bool)pool.supply); + ASSERT_EQ(0, pool.nbTapes); + ASSERT_EQ(0, pool.capacityBytes); + ASSERT_EQ(0, pool.dataBytes); + ASSERT_EQ(0, pool.nbPhysicalFiles); + ASSERT_EQ(secondPoolComment, pool.comment); + + const common::dataStructures::EntryLog creationLog = pool.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + } +} + TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute) { using namespace cta; diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index e05502d22aaec145f65bc6eb6396315bd33e2ae4..caad5b8da5da1d469947ed00c663ebaa2662302f 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -93,7 +93,7 @@ public: std::list<common::dataStructures::RequesterMountRule> getRequesterMountRules() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } std::list<common::dataStructures::StorageClass> getStorageClasses() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } common::dataStructures::ArchiveFileSummary getTapeFileSummary(const TapeFileSearchCriteria& searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } - std::list<TapePool> getTapePools() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + std::list<TapePool> getTapePools(const TapePoolSearchCriteria &searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } cta::optional<TapePool> getTapePool(const std::string &tapePoolName) const override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } std::list<common::dataStructures::Tape> getTapes(const TapeSearchCriteria& searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } // getTapesByVid is implemented below (and works). diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index 511d100b42843b0de1dbc5b41982acf7bc118796..0288bd9328d8f7ecd8e6eb20b5369e764a88b79c 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -2194,13 +2194,42 @@ void RdbmsCatalogue::deleteTapePool(const std::string &name) { } } + //------------------------------------------------------------------------------ // getTapePools //------------------------------------------------------------------------------ -std::list<TapePool> RdbmsCatalogue::getTapePools() const { +std::list<TapePool> RdbmsCatalogue::getTapePools(const TapePoolSearchCriteria &searchCriteria) const { try { + auto conn = m_connPool.getConn(); + return getTapePools(conn, searchCriteria); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + +std::list<TapePool> RdbmsCatalogue::getTapePools(rdbms::Conn &conn, const TapePoolSearchCriteria &searchCriteria) const { + if (isSetAndEmpty(searchCriteria.name)) throw exception::UserError("Pool name cannot be an empty string"); + if (isSetAndEmpty(searchCriteria.vo)) throw exception::UserError("Virtual organisation cannot be an empty string"); + try { + + if (searchCriteria.name && !tapePoolExists(conn, searchCriteria.name.value())) { + UserSpecifiedANonExistentTapePool ex; + ex.getMessage() << "Cannot list tape pools because tape pool " + searchCriteria.name.value() + " does not exist"; + throw ex; + } + + if (searchCriteria.vo && !virtualOrganizationExists(conn, searchCriteria.vo.value())) { + UserSpecifiedANonExistentVirtualOrganization ex; + ex.getMessage() << "Cannot list tape pools because virtual organization " + searchCriteria.vo.value() + " does not exist"; + throw ex; + } + std::list<TapePool> pools; - const char *const sql = + std::string sql = "SELECT " "TAPE_POOL.TAPE_POOL_NAME AS TAPE_POOL_NAME," "VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_NAME AS VO," @@ -2233,27 +2262,61 @@ std::list<TapePool> RdbmsCatalogue::getTapePools() const { "LEFT OUTER JOIN TAPE ON " "TAPE_POOL.TAPE_POOL_ID = TAPE.TAPE_POOL_ID " "LEFT OUTER JOIN MEDIA_TYPE ON " - "TAPE.MEDIA_TYPE_ID = MEDIA_TYPE.MEDIA_TYPE_ID " - "GROUP BY " - "TAPE_POOL.TAPE_POOL_NAME," - "VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_NAME," - "TAPE_POOL.NB_PARTIAL_TAPES," - "TAPE_POOL.IS_ENCRYPTED," - "TAPE_POOL.SUPPLY," - "TAPE_POOL.USER_COMMENT," - "TAPE_POOL.CREATION_LOG_USER_NAME," - "TAPE_POOL.CREATION_LOG_HOST_NAME," - "TAPE_POOL.CREATION_LOG_TIME," - "TAPE_POOL.LAST_UPDATE_USER_NAME," - "TAPE_POOL.LAST_UPDATE_HOST_NAME," - "TAPE_POOL.LAST_UPDATE_TIME " - "ORDER BY " - "TAPE_POOL_NAME"; + "TAPE.MEDIA_TYPE_ID = MEDIA_TYPE.MEDIA_TYPE_ID"; + + if (searchCriteria.name || searchCriteria.vo || searchCriteria.encrypted) { + sql += " WHERE "; + } + bool addedAWhereConstraint = false; + if (searchCriteria.name) { + sql += "TAPE_POOL.TAPE_POOL_NAME = :NAME"; + addedAWhereConstraint = true; + } + + if (searchCriteria.vo) { + if (addedAWhereConstraint) sql += " AND "; + sql += "VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_NAME = :VO"; + addedAWhereConstraint = true; + } + + if (searchCriteria.encrypted) { + if (addedAWhereConstraint) sql += " AND "; + sql += "TAPE_POOL.IS_ENCRYPTED = :ENCRYPTED"; + } + + sql += + " GROUP BY " + "TAPE_POOL.TAPE_POOL_NAME," + "VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_NAME," + "TAPE_POOL.NB_PARTIAL_TAPES," + "TAPE_POOL.IS_ENCRYPTED," + "TAPE_POOL.SUPPLY," + "TAPE_POOL.USER_COMMENT," + "TAPE_POOL.CREATION_LOG_USER_NAME," + "TAPE_POOL.CREATION_LOG_HOST_NAME," + "TAPE_POOL.CREATION_LOG_TIME," + "TAPE_POOL.LAST_UPDATE_USER_NAME," + "TAPE_POOL.LAST_UPDATE_HOST_NAME," + "TAPE_POOL.LAST_UPDATE_TIME " + "ORDER BY " + "TAPE_POOL_NAME"; - auto conn = m_connPool.getConn(); auto stmt = conn.createStmt(sql); stmt.bindString(":STATE_DISABLED",common::dataStructures::Tape::stateToString(common::dataStructures::Tape::DISABLED)); stmt.bindString(":STATE_ACTIVE",common::dataStructures::Tape::stateToString(common::dataStructures::Tape::ACTIVE)); + + if (searchCriteria.name) { + stmt.bindString(":NAME", searchCriteria.name.value()); + } + + if (searchCriteria.vo) { + stmt.bindString(":VO", searchCriteria.vo.value()); + } + + if(searchCriteria.encrypted) { + stmt.bindBool(":ENCRYPTED", searchCriteria.encrypted.value()); + } + auto rset = stmt.executeQuery(); while (rset.next()) { TapePool pool; diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index 98f59bcf326588dfa447a52f448fc81498168bdf..0c3bcf6d58ccc782cc33b6e27e18c2721936ac20 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -431,7 +431,9 @@ public: void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) override; void deleteTapePool(const std::string &name) override; - std::list<TapePool> getTapePools() const override; + std::list<TapePool> getTapePools(const TapePoolSearchCriteria &searchCriteria) const override; + + std::list<TapePool> getTapePools(rdbms::Conn &conn, const TapePoolSearchCriteria &searchCriteria) const; /** * @return The tape pool with the specified name. diff --git a/catalogue/TapePoolSearchCriteria.hpp b/catalogue/TapePoolSearchCriteria.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6e38265cd1f1918b33988e48207a8ede577491c6 --- /dev/null +++ b/catalogue/TapePoolSearchCriteria.hpp @@ -0,0 +1,57 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 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 <string> +#include <vector> + +#include <common/optional.hpp> + +namespace cta { +namespace catalogue { + +/** + * The collection of criteria used to select a set of tapepools. + * + * A tapepool is selected if it meets all of the specified criteria. + * + * A criterion is only considered specified if it has been set. + * + * Please note that no wild cards, for example '*' or '%', are supported. + */ +struct TapePoolSearchCriteria { + + /** + * The name of the tapepool. + */ + optional<std::string> name; + + /** + * The virtual organization of the tapepool. + */ + optional<std::string> vo; + + /** + * Set to true if searching for encrypted tape pools. + */ + optional<bool> encrypted; + +}; // struct TapePoolSearchCriteria + +} // namespace catalogue +} // namespace cta \ No newline at end of file diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index a629108e4a353710a6802105f89864fd63b53929..7f18c1bcfe922d83db753791ae88493a9de25008 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -297,7 +297,7 @@ const std::map<std::string, OptionUInt64::Key> uint64Options = { * Map string options to Protocol Buffer enum values */ const std::map<std::string, OptionString::Key> strOptions = { - { "--bufferurl", OptionString::BUFFERURL }, + { "--bufferurl", OptionString::BUFFERURL }, { "--cartridge", OptionString::CARTRIDGE }, { "--comment", OptionString::COMMENT }, { "--drive", OptionString::DRIVE }, @@ -592,7 +592,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 }, { }}, + {{ AdminCmd::CMD_TAPEPOOL, AdminCmd::SUBCMD_LS }, { opt_tapepool.optional(), opt_vo.optional(), opt_encrypted.optional()}}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_ADD }, { opt_disksystem, opt_file_regexp, opt_free_space_query_url, opt_refresh_interval, opt_targeted_free_space, opt_sleep_time, diff --git a/xroot_plugins/XrdCtaTapePoolLs.hpp b/xroot_plugins/XrdCtaTapePoolLs.hpp index 5a6481674476359092ffdd9ee24e00de9a9a5596..ed8f57715a233c249dc62bb17ea40403997585fe 100644 --- a/xroot_plugins/XrdCtaTapePoolLs.hpp +++ b/xroot_plugins/XrdCtaTapePoolLs.hpp @@ -19,6 +19,7 @@ #include <xroot_plugins/XrdCtaStream.hpp> #include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> +#include <catalogue/TapePoolSearchCriteria.hpp> namespace cta { namespace xrd { @@ -63,6 +64,13 @@ TapePoolLsStream::TapePoolLsStream(const RequestMessage &requestMsg, cta::catalo using namespace cta::admin; XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "TapePoolLsStream() constructor"); + cta::catalogue::TapePoolSearchCriteria searchCriteria; + + searchCriteria.name = requestMsg.getOptional(OptionString_Key_TAPE_POOL); + searchCriteria.vo = requestMsg.getOptional(OptionString_Key_VO); + searchCriteria.encrypted = requestMsg.getOptional(OptionBoolean_Key_ENCRYPTED); + + m_tapePoolList = m_catalogue.getTapePools(searchCriteria); } int TapePoolLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) {