Commit 3aaa2823 authored by Cedric CAFFY's avatar Cedric CAFFY
Browse files

Implemented Catalogue::deleteVirtualOrganization + NOT ALL unit tests

parent 1ad142e6
......@@ -83,7 +83,10 @@ set (CATALOGUE_LIB_SRC_FILES
UserSpecifiedStorageClassUsedByArchiveFiles.cpp
UserSpecifiedStorageClassUsedByArchiveRoutes.cpp
UserSpecifiedAZeroCapacity.cpp
UserSpecifiedAZeroCopyNb.cpp)
UserSpecifiedAZeroCopyNb.cpp
UserSpecifiedVirtualOrganizationUsedByTapepools.cpp
UserSpecifiedVirtualOrganizationUsedByStorageClasses.cpp
)
add_library (ctacatalogue SHARED
${CATALOGUE_LIB_SRC_FILES})
......
......@@ -233,6 +233,12 @@ public:
*/
virtual void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) = 0;
/**
* Deletes the specified Virtual Organization
* @param voName the name of the VirtualOrganization to delete
*/
virtual void deleteVirtualOrganization(const std::string &voName) = 0;
/**
* Creates the specified storage class.
*
......@@ -247,7 +253,7 @@ public:
* Deletes the specified storage class.
*
* @param storageClassName The name of the storage class which is only
* guaranteed to be unique within its disk isntance.
* guaranteed to be unique within its disk instance.
*/
virtual void deleteStorageClass(const std::string &storageClassName) = 0;
......
......@@ -119,6 +119,10 @@ public:
void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->createVirtualOrganization(admin, vo);}, m_maxTriesToConnect);
}
void deleteVirtualOrganization(const std::string &voName) override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->deleteVirtualOrganization(voName);}, 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);
......
......@@ -15325,4 +15325,28 @@ TEST_P(cta_catalogue_CatalogueTest, createVirtualOrganizationEmptyName) {
ASSERT_THROW(m_catalogue->createVirtualOrganization(m_admin,vo),cta::exception::UserError);
}
 
TEST_P(cta_catalogue_CatalogueTest, deleteVirtualOrganization) {
using namespace cta;
common::dataStructures::VirtualOrganization vo;
vo.name = "vo";
vo.comment = "comment";
ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo));
ASSERT_NO_THROW(m_catalogue->deleteVirtualOrganization(vo.name));
}
TEST_P(cta_catalogue_CatalogueTest, deleteVirtualOrganizationNameDoesNotExist) {
using namespace cta;
common::dataStructures::VirtualOrganization vo;
vo.name = "vo";
vo.comment = "comment";
ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo));
ASSERT_THROW(m_catalogue->deleteVirtualOrganization("DOES_NOT_EXIST"),cta::exception::UserError);
}
} // namespace unitTests
......@@ -89,6 +89,7 @@ public:
void modifyAdminUserComment(const common::dataStructures::SecurityIdentity& admin, const std::string& username, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
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"); }
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 &currentName, const std::string &newName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
......
......@@ -395,6 +395,45 @@ void RdbmsCatalogue::createVirtualOrganization(const common::dataStructures::Sec
}
}
//------------------------------------------------------------------------------
// deleteVirtualOrganization
//------------------------------------------------------------------------------
void RdbmsCatalogue::deleteVirtualOrganization(const std::string &voName){
try {
auto conn = m_connPool.getConn();
if(virtualOrganizationIsUsedByStorageClasses(conn, voName)) {
throw UserSpecifiedStorageClassUsedByArchiveRoutes(std::string("The ") + voName +
" Virtual Organization is being used by one or more storage classes");
}
if(virtualOrganizationIsUsedByTapepools(conn, voName)) {
throw UserSpecifiedStorageClassUsedByArchiveFiles(std::string("The ") + voName +
" Virtual Organization is being used by one or more Tapepools");
}
const char *const sql =
"DELETE FROM "
"VIRTUAL_ORGANIZATION "
"WHERE "
"VIRTUAL_ORGANIZATION_NAME = :VIRTUAL_ORGANIZATION_NAME";
auto stmt = conn.createStmt(sql);
stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", voName);
stmt.executeNonQuery();
if(0 == stmt.getNbAffectedRows()) {
throw exception::UserError(std::string("Cannot delete Virtual Organization : ") +
voName + " because it does not exist");
}
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
......@@ -600,6 +639,62 @@ bool RdbmsCatalogue::storageClassIsUsedByArchiveFiles(rdbms::Conn &conn, const s
}
}
//------------------------------------------------------------------------------
// virtualOrganizationIsUsedByStorageClasses
//------------------------------------------------------------------------------
bool RdbmsCatalogue::virtualOrganizationIsUsedByStorageClasses(rdbms::Conn &conn, const std::string &voName) const {
try {
const char *const sql =
"SELECT "
"VIRTUAL_ORGANIZATION_NAME AS VIRTUAL_ORGANIZATION_NAME "
"FROM "
"VIRTUAL_ORGANIZATION "
"INNER JOIN "
"STORAGE_CLASS "
"ON "
"VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_ID = STORAGE_CLASS.VIRTUAL_ORGANIZATION_ID "
"WHERE "
"VIRTUAL_ORGANIZATION_NAME = :VIRTUAL_ORGANIZATION_NAME";
auto stmt = conn.createStmt(sql);
stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", voName);
auto rset = stmt.executeQuery();
return rset.next();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// virtualOrganizationIsUsedByTapepools
//------------------------------------------------------------------------------
bool RdbmsCatalogue::virtualOrganizationIsUsedByTapepools(rdbms::Conn &conn, const std::string &voName) const {
try {
const char *const sql =
"SELECT "
"VIRTUAL_ORGANIZATION_NAME AS VIRTUAL_ORGANIZATION_NAME "
"FROM "
"VIRTUAL_ORGANIZATION "
"INNER JOIN "
"TAPE_POOL "
"ON "
"VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_ID = TAPE_POOL.VIRTUAL_ORGANIZATION_ID "
"WHERE "
"VIRTUAL_ORGANIZATION_NAME = :VIRTUAL_ORGANIZATION_NAME";
auto stmt = conn.createStmt(sql);
stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", voName);
auto rset = stmt.executeQuery();
return rset.next();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// getStorageClasses
//------------------------------------------------------------------------------
......
......@@ -218,6 +218,12 @@ public:
* @param vo the Virtual Organization
*/
void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override;
/**
* Deletes the specified Virtual Organization
* @param voName the name of the VirtualOrganization to delete
*/
void deleteVirtualOrganization(const std::string &voName) override;
/**
* Creates the specified storage class.
......@@ -1551,6 +1557,24 @@ protected:
* @param storageClassName The name of the storage class.
*/
bool storageClassIsUsedByArchiveFiles(rdbms::Conn &conn, const std::string &storageClassName) const;
/**
* Returns true if the specified Virtual Organization is currently being used by one
* or more StorageClasses
*
* @param conn The database connection.
* @param voName The name of the Virtual Organization.
*/
bool virtualOrganizationIsUsedByStorageClasses(rdbms::Conn &conn, const std::string &voName) const;
/**
* Returns true if the specified Virtual Organization is currently being used by one
* or more Tapepools
*
* @param conn The database connection.
* @param voName The name of the Virtual Organization.
*/
bool virtualOrganizationIsUsedByTapepools(rdbms::Conn &conn, const std::string &voName) const;
/**
* Returns the ID of the specified logical library or nullopt if the logical
......
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/UserSpecifiedVirtualOrganizationUsedByStorageClasses.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
UserSpecifiedVirtualOrganizationUsedByStorageClasses::UserSpecifiedVirtualOrganizationUsedByStorageClasses(const std::string &context,
const bool embedBacktrace): cta::exception::UserError(context, embedBacktrace) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
UserSpecifiedVirtualOrganizationUsedByStorageClasses::~UserSpecifiedVirtualOrganizationUsedByStorageClasses() {
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/exception/UserError.hpp"
namespace cta {
namespace catalogue {
/**
* User specified a storage class which is currently being used by one or more
* archive files.
*/
class UserSpecifiedVirtualOrganizationUsedByStorageClasses: public exception::UserError {
public:
/**
* Constructor.
*
* @param context optional context string added to the message
* at initialisation time.
* @param embedBacktrace whether to embed a backtrace of where the
* exception was throw in the message
*/
UserSpecifiedVirtualOrganizationUsedByStorageClasses(const std::string &context = "", const bool embedBacktrace = true);
/**
* Destructor.
*/
~UserSpecifiedVirtualOrganizationUsedByStorageClasses() override;
}; // class UserSpecifiedVirtualOrganizationUsedByStorageClasses
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/UserSpecifiedVirtualOrganizationUsedByTapepools.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
UserSpecifiedVirtualOrganizationUsedByTapepools::UserSpecifiedVirtualOrganizationUsedByTapepools(const std::string &context,
const bool embedBacktrace): cta::exception::UserError(context, embedBacktrace) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
UserSpecifiedVirtualOrganizationUsedByTapepools::~UserSpecifiedVirtualOrganizationUsedByTapepools() {
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/exception/UserError.hpp"
namespace cta {
namespace catalogue {
/**
* User specified a storage class which is currently being used by one or more
* archive files.
*/
class UserSpecifiedVirtualOrganizationUsedByTapepools: public exception::UserError {
public:
/**
* Constructor.
*
* @param context optional context string added to the message
* at initialisation time.
* @param embedBacktrace whether to embed a backtrace of where the
* exception was throw in the message
*/
UserSpecifiedVirtualOrganizationUsedByTapepools(const std::string &context = "", const bool embedBacktrace = true);
/**
* Destructor.
*/
~UserSpecifiedVirtualOrganizationUsedByTapepools() override;
}; // class UserSpecifiedVirtualOrganizationUsedByTapepools
} // namespace catalogue
} // namespace cta
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment