Commit f68c5bdf authored by Steven Murray's avatar Steven Murray
Browse files

Added Catalogue::modifyTapePoolSupply()

parent 858febbf
......@@ -58,6 +58,7 @@ set (CATALOGUE_LIB_SRC_FILES
UserSpecifiedAnEmptyStringLogicalLibraryName.cpp
UserSpecifiedAnEmptyStringMediaType.cpp
UserSpecifiedAnEmptyStringStorageClassName.cpp
UserSpecifiedAnEmptyStringSupply.cpp
UserSpecifiedAnEmptyStringTapePoolName.cpp
UserSpecifiedAnEmptyStringUsername.cpp
UserSpecifiedAnEmptyStringVendor.cpp
......
......@@ -246,6 +246,7 @@ public:
virtual void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbPartialTapes) = 0;
virtual void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0;
virtual void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool encryptionValue) = 0;
virtual void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) = 0;
virtual void createArchiveRoute(
const common::dataStructures::SecurityIdentity &admin,
......
......@@ -165,6 +165,10 @@ public:
return retryOnLostConnection(m_log, [&]{return m_catalogue->setTapePoolEncryption(admin, name, encryptionValue);}, m_maxTriesToConnect);
}
void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyTapePoolSupply(admin, name, supply);}, m_maxTriesToConnect);
}
void createArchiveRoute(const common::dataStructures::SecurityIdentity &admin, const std::string &diskInstanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &tapePoolName, const std::string &comment) override {
return retryOnLostConnection(m_log, [&]{return m_catalogue->createArchiveRoute(admin, diskInstanceName, storageClassName, copyNb, tapePoolName, comment);}, m_maxTriesToConnect);
}
......
......@@ -28,6 +28,7 @@
#include "catalogue/UserSpecifiedAnEmptyStringLogicalLibraryName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringMediaType.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringStorageClassName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringSupply.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringTapePoolName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringUsername.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringVendor.hpp"
......@@ -1470,6 +1471,139 @@ TEST_P(cta_catalogue_CatalogueTest, setTapePoolEncryption_nonExistentTapePool) {
ASSERT_THROW(m_catalogue->setTapePoolEncryption(m_admin, tapePoolName, isEncrypted), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply) {
using namespace cta;
ASSERT_TRUE(m_catalogue->getTapePools().empty());
const std::string tapePoolName = "tape_pool";
const std::string vo = "vo";
const uint64_t nbPartialTapes = 2;
const bool isEncrypted = true;
const cta::optional<std::string> supply("value for the supply pool mechanism");
const std::string comment = "Create tape pool";
m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
{
const auto pools = m_catalogue->getTapePools();
ASSERT_EQ(1, pools.size());
const auto &pool = pools.front();
ASSERT_EQ(tapePoolName, pool.name);
ASSERT_EQ(vo, pool.vo);
ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
ASSERT_EQ(isEncrypted, pool.encryption);
ASSERT_TRUE((bool)supply);
ASSERT_EQ(supply.value(), pool.supply.value());
ASSERT_EQ(supply, pool.supply);
ASSERT_EQ(0, pool.nbTapes);
ASSERT_EQ(0, pool.capacityBytes);
ASSERT_EQ(0, pool.dataBytes);
ASSERT_EQ(0, pool.nbPhysicalFiles);
ASSERT_EQ(comment, pool.comment);
const common::dataStructures::EntryLog creationLog = pool.creationLog;
ASSERT_EQ(m_admin.username, creationLog.username);
ASSERT_EQ(m_admin.host, creationLog.host);
const common::dataStructures::EntryLog lastModificationLog = pool.lastModificationLog;
ASSERT_EQ(creationLog, lastModificationLog);
}
const std::string modifiedSupply("Modified supply");
m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply);
{
const auto pools = m_catalogue->getTapePools();
ASSERT_EQ(1, pools.size());
const auto &pool = pools.front();
ASSERT_EQ(tapePoolName, pool.name);
ASSERT_EQ(vo, pool.vo);
ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
ASSERT_EQ(isEncrypted, pool.encryption);
ASSERT_TRUE((bool)supply);
ASSERT_EQ(modifiedSupply, pool.supply.value());
ASSERT_EQ(0, pool.nbTapes);
ASSERT_EQ(0, pool.capacityBytes);
ASSERT_EQ(0, pool.dataBytes);
ASSERT_EQ(0, pool.nbPhysicalFiles);
ASSERT_EQ(comment, 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, modifyTapePoolSupply_emptyStringTapePoolName) {
using namespace cta;
ASSERT_TRUE(m_catalogue->getTapePools().empty());
const std::string tapePoolName = "";
const std::string modifiedSupply = "Modified supply";
ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply),
catalogue::UserSpecifiedAnEmptyStringTapePoolName);
}
TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_emptyStringSupply) {
using namespace cta;
ASSERT_TRUE(m_catalogue->getTapePools().empty());
const std::string tapePoolName = "tape_pool";
const std::string vo = "vo";
const uint64_t nbPartialTapes = 2;
const bool isEncrypted = true;
const cta::optional<std::string> supply("value for the supply pool mechanism");
const std::string comment = "Create tape pool";
m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
{
const auto pools = m_catalogue->getTapePools();
ASSERT_EQ(1, pools.size());
const auto &pool = pools.front();
ASSERT_EQ(tapePoolName, pool.name);
ASSERT_EQ(vo, pool.vo);
ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
ASSERT_EQ(isEncrypted, pool.encryption);
ASSERT_TRUE((bool)supply);
ASSERT_EQ(supply.value(), pool.supply.value());
ASSERT_EQ(supply, pool.supply);
ASSERT_EQ(0, pool.nbTapes);
ASSERT_EQ(0, pool.capacityBytes);
ASSERT_EQ(0, pool.dataBytes);
ASSERT_EQ(0, pool.nbPhysicalFiles);
ASSERT_EQ(comment, pool.comment);
const common::dataStructures::EntryLog creationLog = pool.creationLog;
ASSERT_EQ(m_admin.username, creationLog.username);
ASSERT_EQ(m_admin.host, creationLog.host);
const common::dataStructures::EntryLog lastModificationLog = pool.lastModificationLog;
ASSERT_EQ(creationLog, lastModificationLog);
}
const std::string modifiedSupply = "";
ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply),
catalogue::UserSpecifiedAnEmptyStringSupply);
}
TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_nonExistentTapePool) {
using namespace cta;
ASSERT_TRUE(m_catalogue->getTapePools().empty());
const std::string tapePoolName = "tape_pool";
const std::string supply = "value for the supply pool mechanism";
ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, supply), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute) {
using namespace cta;
......
......@@ -97,6 +97,7 @@ public:
void modifyTapePoolComment(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void modifyTapePoolVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t nbPartialTapes) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& supply) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void noSpaceLeftOnTape(const std::string& vid) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
void ping() override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
......
......@@ -29,6 +29,7 @@
#include "catalogue/UserSpecifiedAnEmptyStringLogicalLibraryName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringMediaType.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringStorageClassName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringSupply.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringTapePoolName.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringUsername.hpp"
#include "catalogue/UserSpecifiedAnEmptyStringVendor.hpp"
......@@ -1131,6 +1132,51 @@ void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::Securit
}
}
//------------------------------------------------------------------------------
// modifyTapePoolSupply
//------------------------------------------------------------------------------
void RdbmsCatalogue::modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin,
const std::string &name, const std::string &supply) {
try {
if(name.empty()) {
throw UserSpecifiedAnEmptyStringTapePoolName("Cannot modify tape pool because the tape pool name is an empty"
" string");
}
if(supply.empty()) {
throw UserSpecifiedAnEmptyStringSupply("Cannot modify tape pool because the new supply value is an empty"
" string");
}
const time_t now = time(nullptr);
const char *const sql =
"UPDATE TAPE_POOL SET "
"SUPPLY = :SUPPLY,"
"LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
"LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
"LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
"WHERE "
"TAPE_POOL_NAME = :TAPE_POOL_NAME";
auto conn = m_connPool.getConn();
auto stmt = conn.createStmt(sql);
stmt.bindString(":SUPPLY", supply);
stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
stmt.bindUint64(":LAST_UPDATE_TIME", now);
stmt.bindString(":TAPE_POOL_NAME", name);
stmt.executeNonQuery();
if(0 == stmt.getNbAffectedRows()) {
throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
}
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
throw;
}
}
//------------------------------------------------------------------------------
// createArchiveRoute
//------------------------------------------------------------------------------
......
......@@ -240,6 +240,7 @@ public:
void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbPartialTapes) override;
void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override;
void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool encryptionValue) override;
void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) override;
void createArchiveRoute(
const common::dataStructures::SecurityIdentity &admin,
......
/*
* 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/UserSpecifiedAnEmptyStringSupply.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
UserSpecifiedAnEmptyStringSupply::UserSpecifiedAnEmptyStringSupply(const std::string &context,
const bool embedBacktrace): cta::exception::UserError(context, embedBacktrace) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
UserSpecifiedAnEmptyStringSupply::~UserSpecifiedAnEmptyStringSupply() {
}
} // 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 an empty string for a supply value when this is not permitted.
*/
class UserSpecifiedAnEmptyStringSupply: 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
*/
UserSpecifiedAnEmptyStringSupply(const std::string &context = "", const bool embedBacktrace = true);
/**
* Destructor.
*/
~UserSpecifiedAnEmptyStringSupply() override;
}; // class UserSpecifiedAnEmptyStringSupply
} // namespace catalogue
} // namespace cta
Supports Markdown
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