diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index b0bc95b3c6ddee4e43426208af6ccb7618213f36..483c29b1216a6727ac7c375ce09df78854bb8bf7 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -245,6 +245,14 @@ public: */ virtual std::list<common::dataStructures::VirtualOrganization> getVirtualOrganizations() const = 0; + /** + * Modifies the name of the specified Virtual Organization. + * + * @param currentVoName The current name of the Virtual Organization. + * @param newVoName The new name of the Virtual Organization. + */ + virtual void modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tVoName, const std::string &newVoName) = 0; + /** * Creates the specified storage class. * diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index 2da57cb123d317e3df07958d93adb719357fed69..0c405e6a56e74084d902c896f916a6a6b22b471e 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -127,6 +127,10 @@ public: std::list<common::dataStructures::VirtualOrganization> getVirtualOrganizations() const override { return retryOnLostConnection(m_log, [&]{return m_catalogue->getVirtualOrganizations();}, m_maxTriesToConnect); } + + void modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tVoName, const std::string &newVoName) override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyVirtualOrganizationName(admin,currentVoName,newVoName);}, m_maxTriesToConnect); + } void createStorageClass(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::StorageClass &storageClass) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->createStorageClass(admin, storageClass);}, m_maxTriesToConnect); diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index 0720529395addfca86bcf0645ee065ef70419579..29f3c16a9c797e10a8e1a058609cf3dd1f8f0f52 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -15381,4 +15381,47 @@ TEST_P(cta_catalogue_CatalogueTest, getVirtualOrganizations) { ASSERT_EQ(0,vos.size()); } +TEST_P(cta_catalogue_CatalogueTest, modifyVirtualOrganization) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo; + vo.name = "vo"; + vo.comment = "comment"; + + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); + + std::string newVoName = "NewVoName"; + + ASSERT_NO_THROW(m_catalogue->modifyVirtualOrganizationName(m_admin,vo.name,newVoName)); + + auto vos = m_catalogue->getVirtualOrganizations(); + + auto voFront = vos.front(); + ASSERT_EQ(newVoName,voFront.name); +} + +TEST_P(cta_catalogue_CatalogueTest, modifyVirtualOrganizationDoesNotExists) { + using namespace cta; + + ASSERT_THROW(m_catalogue->modifyVirtualOrganizationName(m_admin,"DOES_NOT_EXIST","NEW_NAME"),cta::exception::UserError); +} + +TEST_P(cta_catalogue_CatalogueTest, modifyVirtualOrganizationNameThatAlreadyExists) { + using namespace cta; + + std::string voName = "vo"; + std::string vo2Name = "vo2"; + + common::dataStructures::VirtualOrganization vo; + vo.name = voName; + vo.comment = "comment"; + + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); + + vo.name = vo2Name; + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); + + ASSERT_THROW(m_catalogue->modifyVirtualOrganizationName(m_admin,"vo","vo2"),cta::exception::UserError); +} + } // namespace unitTests diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index 550d21a5677e41ea2d8a0d165cec4600de917434..5621dc5dcf9c17134e921c38af084f546f163b16 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -91,6 +91,7 @@ public: void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void deleteVirtualOrganization(const std::string &voName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } std::list<common::dataStructures::VirtualOrganization> getVirtualOrganizations() const override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + void modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tVoName, const std::string &newVoName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyLogicalLibraryName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tName, const std::string &newName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index 90c09b11685f14725b1e7d9f900add05cca2abc1..8992d6507deae1e6f0e13e6d88b5b200637ffeea 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -485,6 +485,45 @@ std::list<common::dataStructures::VirtualOrganization> RdbmsCatalogue::getVirtua } } +//------------------------------------------------------------------------------ +// modifyVirtualOrganizationName +//------------------------------------------------------------------------------ +void RdbmsCatalogue::modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity& admin, const std::string& currentVoName, const std::string& newVoName) { + try { + const time_t now = time(nullptr); + const char *const sql = + "UPDATE VIRTUAL_ORGANIZATION SET " + "VIRTUAL_ORGANIZATION_NAME = :NEW_VIRTUAL_ORGANIZATION_NAME," + "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME," + "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME," + "LAST_UPDATE_TIME = :LAST_UPDATE_TIME " + "WHERE " + "VIRTUAL_ORGANIZATION_NAME = :CURRENT_VIRTUAL_ORGANIZATION_NAME"; + auto conn = m_connPool.getConn(); + if(newVoName != currentVoName){ + if(virtualOrganizationExists(conn,newVoName)){ + throw exception::UserError(std::string("Cannot modify the virtual organization name ") + currentVoName +". The new name : " + newVoName+" already exists in the database."); + } + } + auto stmt = conn.createStmt(sql); + stmt.bindString(":NEW_VIRTUAL_ORGANIZATION_NAME", newVoName); + stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username); + stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host); + stmt.bindUint64(":LAST_UPDATE_TIME", now); + stmt.bindString(":CURRENT_VIRTUAL_ORGANIZATION_NAME", currentVoName); + stmt.executeNonQuery(); + + if(0 == stmt.getNbAffectedRows()) { + throw exception::UserError(std::string("Cannot modify virtual organization : ") + currentVoName + + " because it does not exist"); + } + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} //------------------------------------------------------------------------------ // createStorageClass diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index fe7a17dddcc26090634089c3f57ac59dfb5dae14..b1eed37ee4d2a4357b863d72ed00fd346a8c9d0f 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -230,6 +230,14 @@ public: * @return the list of all the Virtual Organizations */ std::list<common::dataStructures::VirtualOrganization> getVirtualOrganizations() const override; + + /** + * Modifies the name of the specified Virtual Organization. + * + * @param currentVoName The current name of the Virtual Organization. + * @param newVoName The new name of the Virtual Organization. + */ + void modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tVoName, const std::string &newVoName) override; /** * Creates the specified storage class.