From 2311251500d3339f5f3c8d3802c35f0d4dc2c020 Mon Sep 17 00:00:00 2001 From: Steven Murray <steven.murray@cern.ch> Date: Mon, 8 Aug 2016 09:08:09 +0200 Subject: [PATCH] Implemented Rdbms::reclaimTape() --- catalogue/Catalogue.hpp | 14 + catalogue/CatalogueTest.cpp | 491 ++++++++++++++++++++++++++++++++++ catalogue/OracleCatalogue.cpp | 1 + catalogue/OracleCatalogue.hpp | 8 +- catalogue/RdbmsCatalogue.cpp | 80 +++++- catalogue/RdbmsCatalogue.hpp | 199 ++++++++------ catalogue/SqliteCatalogue.hpp | 4 +- 7 files changed, 694 insertions(+), 103 deletions(-) diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 86b0527486..04a95aae1e 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -299,7 +299,21 @@ public: */ virtual common::dataStructures::VidToTapeMap getTapesByVid(const std::set<std::string> &vids) const = 0; + /** + * Reclaims the specified tape. + * + * This method will throw an exception if the specified tape does not exist. + * + * This method will throw an exception if the specified tape is not FULL. + * + * This method will throw an exception if there is still at least one tape + * file recorded in the cataligue as being on the specified tape. + * + * @param cliIdentity The user of the command-line tool. + * @param vid The volume identifier of the tape to be reclaimed. + */ virtual void reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) = 0; + virtual void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &logicalLibraryName) = 0; virtual void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &tapePoolName) = 0; virtual void modifyTapeCapacityInBytes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const uint64_t capacityInBytes) = 0; diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index 103b4315a1..259ad07d72 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -6398,4 +6398,495 @@ TEST_P(cta_catalogue_CatalogueTest, getTapesByVid_no_vids) { ASSERT_TRUE(m_catalogue->getTapesByVid(vids).empty()); } +TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_0_no_tape_files) { + using namespace cta; + + ASSERT_TRUE(m_catalogue->getTapes().empty()); + + const std::string vid = "vid"; + const std::string logicalLibraryName = "logical_library_name"; + const std::string tapePoolName = "tape_pool_name"; + const std::string encryptionKey = "encryption_key"; + const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000; + const bool disabledValue = true; + const bool fullValue = false; + const std::string comment = "Create tape"; + + m_catalogue->createLogicalLibrary(m_cliSI, logicalLibraryName, + "Create logical library"); + m_catalogue->createTapePool(m_cliSI, tapePoolName, 2, true, "Create tape pool"); + m_catalogue->createTape(m_cliSI, vid, logicalLibraryName, tapePoolName, encryptionKey, capacityInBytes, disabledValue, + fullValue, comment); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(vid, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(comment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + m_catalogue->setTapeFull(m_cliSI, vid, true); + m_catalogue->reclaimTape(m_cliSI, vid); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(vid, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_FALSE(tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(comment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + } +} + +TEST_P(cta_catalogue_CatalogueTest, reclaimTape_not_full_lastFSeq_0_no_tape_files) { + using namespace cta; + + ASSERT_TRUE(m_catalogue->getTapes().empty()); + + const std::string vid = "vid"; + const std::string logicalLibraryName = "logical_library_name"; + const std::string tapePoolName = "tape_pool_name"; + const std::string encryptionKey = "encryption_key"; + const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000; + const bool disabledValue = true; + const bool fullValue = false; + const std::string comment = "Create tape"; + + m_catalogue->createLogicalLibrary(m_cliSI, logicalLibraryName, + "Create logical library"); + m_catalogue->createTapePool(m_cliSI, tapePoolName, 2, true, "Create tape pool"); + m_catalogue->createTape(m_cliSI, vid, logicalLibraryName, tapePoolName, encryptionKey, capacityInBytes, disabledValue, + fullValue, comment); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(vid, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(comment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + ASSERT_THROW(m_catalogue->reclaimTape(m_cliSI, vid), exception::UserError); +} + +TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) { + using namespace cta; + + const std::string diskInstanceName1 = "disk_instance_1"; + + ASSERT_TRUE(m_catalogue->getTapes().empty()); + + const std::string vid1 = "VID123"; + const std::string logicalLibraryName = "logical_library_name"; + const std::string tapePoolName = "tape_pool_name"; + const std::string encryptionKey = "encryption_key"; + const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000; + const bool disabledValue = true; + const bool fullValue = false; + const std::string createTapeComment = "Create tape"; + + m_catalogue->createLogicalLibrary(m_cliSI, logicalLibraryName, "Create logical library"); + m_catalogue->createTapePool(m_cliSI, tapePoolName, 2, true, "Create tape pool"); + m_catalogue->createTape(m_cliSI, vid1, logicalLibraryName, tapePoolName, encryptionKey, capacityInBytes, + disabledValue, fullValue, createTapeComment); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes); + ASSERT_EQ(1, vidToTape.size()); + + auto it = vidToTape.find(vid1); + const common::dataStructures::Tape &tape = it->second; + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = + tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + const uint64_t archiveFileId = 1234; + + ASSERT_FALSE(m_catalogue->getArchiveFileItor()->hasMore()); + ASSERT_THROW(m_catalogue->getArchiveFileById(archiveFileId), exception::Exception); + + common::dataStructures::StorageClass storageClass; + storageClass.diskInstance = diskInstanceName1; + storageClass.name = "storage_class"; + storageClass.nbCopies = 1; + storageClass.comment = "Create storage class"; + m_catalogue->createStorageClass(m_cliSI, storageClass); + + const uint64_t archiveFileSize = 1; + const std::string tapeDrive = "tape_drive"; + const std::string checksumType = "checksum_type"; + const std::string checksumValue = "checksum_value"; + + catalogue::TapeFileWritten file1Written; + file1Written.archiveFileId = archiveFileId; + file1Written.diskInstance = storageClass.diskInstance; + file1Written.diskFileId = "5678"; + file1Written.diskFilePath = "/public_dir/public_file"; + file1Written.diskFileUser = "public_disk_user"; + file1Written.diskFileGroup = "public_disk_group"; + file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents"; + file1Written.size = archiveFileSize; + file1Written.checksumType = checksumType; + file1Written.checksumValue = checksumValue; + file1Written.storageClassName = storageClass.name; + file1Written.vid = vid1; + file1Written.fSeq = 1; + file1Written.blockId = 4321; + file1Written.compressedSize = 1; + file1Written.copyNb = 1; + file1Written.tapeDrive = tapeDrive; + m_catalogue->fileWrittenToTape(file1Written); + + { + const common::dataStructures::ArchiveFile archiveFile = m_catalogue->getArchiveFileById(archiveFileId); + + ASSERT_EQ(file1Written.archiveFileId, archiveFile.archiveFileID); + ASSERT_EQ(file1Written.diskFileId, archiveFile.diskFileId); + ASSERT_EQ(file1Written.size, archiveFile.fileSize); + ASSERT_EQ(file1Written.checksumType, archiveFile.checksumType); + ASSERT_EQ(file1Written.checksumValue, archiveFile.checksumValue); + ASSERT_EQ(file1Written.storageClassName, archiveFile.storageClass); + + ASSERT_EQ(file1Written.diskInstance, archiveFile.diskInstance); + ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path); + ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner); + ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group); + ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob); + + ASSERT_EQ(1, archiveFile.tapeFiles.size()); + auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1); + ASSERT_FALSE(copyNbToTapeFile1Itor == archiveFile.tapeFiles.end()); + const common::dataStructures::TapeFile &tapeFile1 = copyNbToTapeFile1Itor->second; + ASSERT_EQ(file1Written.vid, tapeFile1.vid); + ASSERT_EQ(file1Written.fSeq, tapeFile1.fSeq); + ASSERT_EQ(file1Written.blockId, tapeFile1.blockId); + ASSERT_EQ(file1Written.compressedSize, tapeFile1.compressedSize); + ASSERT_EQ(file1Written.checksumType, tapeFile1.checksumType); + ASSERT_EQ(file1Written.checksumValue, tapeFile1.checksumValue); + ASSERT_EQ(file1Written.copyNb, tapeFile1.copyNb); + } + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes); + ASSERT_EQ(1, vidToTape.size()); + + auto it = vidToTape.find(vid1); + const common::dataStructures::Tape &tape = it->second; + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(1, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_TRUE((bool)tape.lastWriteLog); + ASSERT_EQ(tapeDrive, tape.lastWriteLog.value().drive); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = + tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + m_catalogue->deleteArchiveFile(diskInstanceName1, file1Written.archiveFileId); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes); + ASSERT_EQ(1, vidToTape.size()); + + auto it = vidToTape.find(vid1); + const common::dataStructures::Tape &tape = it->second; + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(1, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_TRUE((bool)tape.lastWriteLog); + ASSERT_EQ(tapeDrive, tape.lastWriteLog.value().drive); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = + tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + m_catalogue->setTapeFull(m_cliSI, vid1, true); + m_catalogue->reclaimTape(m_cliSI, vid1); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_TRUE((bool)tape.lastWriteLog); + ASSERT_EQ(tapeDrive, tape.lastWriteLog.value().drive); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + } +} + +TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) { + using namespace cta; + + const std::string diskInstanceName1 = "disk_instance_1"; + + ASSERT_TRUE(m_catalogue->getTapes().empty()); + + const std::string vid1 = "VID123"; + const std::string logicalLibraryName = "logical_library_name"; + const std::string tapePoolName = "tape_pool_name"; + const std::string encryptionKey = "encryption_key"; + const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000; + const bool disabledValue = true; + const bool fullValue = false; + const std::string createTapeComment = "Create tape"; + + m_catalogue->createLogicalLibrary(m_cliSI, logicalLibraryName, "Create logical library"); + m_catalogue->createTapePool(m_cliSI, tapePoolName, 2, true, "Create tape pool"); + m_catalogue->createTape(m_cliSI, vid1, logicalLibraryName, tapePoolName, encryptionKey, capacityInBytes, + disabledValue, fullValue, createTapeComment); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes); + ASSERT_EQ(1, vidToTape.size()); + + auto it = vidToTape.find(vid1); + const common::dataStructures::Tape &tape = it->second; + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(0, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = + tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + const uint64_t archiveFileId = 1234; + + ASSERT_FALSE(m_catalogue->getArchiveFileItor()->hasMore()); + ASSERT_THROW(m_catalogue->getArchiveFileById(archiveFileId), exception::Exception); + + common::dataStructures::StorageClass storageClass; + storageClass.diskInstance = diskInstanceName1; + storageClass.name = "storage_class"; + storageClass.nbCopies = 1; + storageClass.comment = "Create storage class"; + m_catalogue->createStorageClass(m_cliSI, storageClass); + + const uint64_t archiveFileSize = 1; + const std::string tapeDrive = "tape_drive"; + const std::string checksumType = "checksum_type"; + const std::string checksumValue = "checksum_value"; + + catalogue::TapeFileWritten file1Written; + file1Written.archiveFileId = archiveFileId; + file1Written.diskInstance = storageClass.diskInstance; + file1Written.diskFileId = "5678"; + file1Written.diskFilePath = "/public_dir/public_file"; + file1Written.diskFileUser = "public_disk_user"; + file1Written.diskFileGroup = "public_disk_group"; + file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents"; + file1Written.size = archiveFileSize; + file1Written.checksumType = checksumType; + file1Written.checksumValue = checksumValue; + file1Written.storageClassName = storageClass.name; + file1Written.vid = vid1; + file1Written.fSeq = 1; + file1Written.blockId = 4321; + file1Written.compressedSize = 1; + file1Written.copyNb = 1; + file1Written.tapeDrive = tapeDrive; + m_catalogue->fileWrittenToTape(file1Written); + + { + const common::dataStructures::ArchiveFile archiveFile = m_catalogue->getArchiveFileById(archiveFileId); + + ASSERT_EQ(file1Written.archiveFileId, archiveFile.archiveFileID); + ASSERT_EQ(file1Written.diskFileId, archiveFile.diskFileId); + ASSERT_EQ(file1Written.size, archiveFile.fileSize); + ASSERT_EQ(file1Written.checksumType, archiveFile.checksumType); + ASSERT_EQ(file1Written.checksumValue, archiveFile.checksumValue); + ASSERT_EQ(file1Written.storageClassName, archiveFile.storageClass); + + ASSERT_EQ(file1Written.diskInstance, archiveFile.diskInstance); + ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path); + ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner); + ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group); + ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob); + + ASSERT_EQ(1, archiveFile.tapeFiles.size()); + auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1); + ASSERT_FALSE(copyNbToTapeFile1Itor == archiveFile.tapeFiles.end()); + const common::dataStructures::TapeFile &tapeFile1 = copyNbToTapeFile1Itor->second; + ASSERT_EQ(file1Written.vid, tapeFile1.vid); + ASSERT_EQ(file1Written.fSeq, tapeFile1.fSeq); + ASSERT_EQ(file1Written.blockId, tapeFile1.blockId); + ASSERT_EQ(file1Written.compressedSize, tapeFile1.compressedSize); + ASSERT_EQ(file1Written.checksumType, tapeFile1.checksumType); + ASSERT_EQ(file1Written.checksumValue, tapeFile1.checksumValue); + ASSERT_EQ(file1Written.copyNb, tapeFile1.copyNb); + } + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes); + ASSERT_EQ(1, vidToTape.size()); + + auto it = vidToTape.find(vid1); + const common::dataStructures::Tape &tape = it->second; + ASSERT_EQ(vid1, tape.vid); + ASSERT_EQ(1, tape.lastFSeq); + ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(tapePoolName, tape.tapePoolName); + ASSERT_EQ(encryptionKey, tape.encryptionKey); + ASSERT_EQ(capacityInBytes, tape.capacityInBytes); + ASSERT_TRUE(disabledValue == tape.disabled); + ASSERT_TRUE(fullValue == tape.full); + ASSERT_FALSE(tape.lbp); + ASSERT_EQ(createTapeComment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_TRUE((bool)tape.lastWriteLog); + ASSERT_EQ(tapeDrive, tape.lastWriteLog.value().drive); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_cliSI.username, creationLog.username); + ASSERT_EQ(m_cliSI.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = + tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + } + + m_catalogue->setTapeFull(m_cliSI, vid1, true); + ASSERT_THROW(m_catalogue->reclaimTape(m_cliSI, vid1), exception::UserError); +} + } // namespace unitTests diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp index 2844d7e717..5f879826e0 100644 --- a/catalogue/OracleCatalogue.cpp +++ b/catalogue/OracleCatalogue.cpp @@ -21,6 +21,7 @@ #include "common/exception/Exception.hpp" #include "common/make_unique.hpp" #include "common/utils/utils.hpp" +#include "rdbms/AutoRollback.hpp" #include "rdbms/ConnFactoryFactory.hpp" namespace cta { diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp index 89dbbb45a9..f60039125a 100644 --- a/catalogue/OracleCatalogue.hpp +++ b/catalogue/OracleCatalogue.hpp @@ -49,7 +49,7 @@ public: /** * Destructor. */ - virtual ~OracleCatalogue() override; + ~OracleCatalogue() override; /** * Deletes the specified archive file and its associated tape copies from the @@ -64,7 +64,7 @@ public: * @return The metadata of the deleted archive file including the metadata of * the associated and also deleted tape copies. */ - virtual common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName, + common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName, const uint64_t archiveFileId) override; /** @@ -79,7 +79,7 @@ public: * @return A unique archive ID that can be used by a new archive file within * the catalogue. */ - virtual uint64_t getNextArchiveFileId(rdbms::Conn &conn) override; + uint64_t getNextArchiveFileId(rdbms::Conn &conn) override; /** * Selects the specified tape within the Tape table for update. @@ -91,7 +91,7 @@ public: * @param conn The database connection. * @param vid The volume identifier of the tape. */ - virtual common::dataStructures::Tape selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) override; + common::dataStructures::Tape selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) override; }; // class OracleCatalogue diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index 5c50f293a7..af75e7f2f7 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -1496,6 +1496,19 @@ void RdbmsCatalogue::deleteTape(const std::string &vid) { // getTapes //------------------------------------------------------------------------------ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(const TapeSearchCriteria &searchCriteria) const { + try { + auto conn = m_connPool.getConn(); + return getTapes(*conn, searchCriteria); + } catch(exception::Exception &ex) { + throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str()); + } +} + +//------------------------------------------------------------------------------ +// getTapes +//------------------------------------------------------------------------------ +std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &conn, + const TapeSearchCriteria &searchCriteria) const { try { std::list<common::dataStructures::Tape> tapes; std::string sql = @@ -1578,8 +1591,7 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(const TapeSearc sql += " LBP_IS_ON = :LBP_IS_ON"; } - auto conn = m_connPool.getConn(); - auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::OFF); + auto stmt = conn.createStmt(sql, rdbms::Stmt::AutocommitMode::OFF); if(searchCriteria.vid) stmt->bindString(":VID", searchCriteria.vid.value()); if(searchCriteria.logicalLibrary) stmt->bindString(":LOGICAL_LIBRARY_NAME", searchCriteria.logicalLibrary.value()); @@ -1729,6 +1741,63 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getTapesByVid(const std::se } } +//------------------------------------------------------------------------------ +// reclaimTape +//------------------------------------------------------------------------------ +void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) { + try { + const time_t now = time(nullptr); + const char *const sql = + "UPDATE TAPE SET " + "LAST_FSEQ = 0, " + "IS_FULL = 0," + "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME," + "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME," + "LAST_UPDATE_TIME = :LAST_UPDATE_TIME " + "WHERE " + "VID = :UPDATE_VID AND " + "IS_FULL != 0 AND " + "NOT EXISTS (SELECT VID FROM TAPE_FILE WHERE VID = :SELECT_VID)"; + auto conn = m_connPool.getConn(); + auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::ON); + stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username); + stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host); + stmt->bindUint64(":LAST_UPDATE_TIME", now); + stmt->bindString(":UPDATE_VID", vid); + stmt->bindString(":SELECT_VID", vid); + stmt->executeNonQuery(); + + // If the update failed due to a user error + if(0 == stmt->getNbAffectedRows()) { + // Try to determine the user error + // + // Please note that this is a best effort diagnosis because there is no + // lock on the database to prevent other concurrent updates from taking + // place on the TAPE and TAPE_FILE tables + TapeSearchCriteria searchCriteria; + searchCriteria.vid = vid; + const auto tapes = getTapes(*conn, searchCriteria); + + if(tapes.empty()) { + throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because it does not exist"); + } else { + if(!tapes.front().full) { + throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because it is not FULL"); + } else { + throw exception::UserError(std::string("Cannot reclaim tape ") + vid + " because there is at least one tape" + " file in the catalogue that is on the tape"); + } + } + } + + conn->commit(); + } catch(exception::UserError &) { + throw; + } catch (exception::Exception &ex) { + throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str()); + } +} + //------------------------------------------------------------------------------ // getTapeLogFromRset //------------------------------------------------------------------------------ @@ -1762,13 +1831,6 @@ optional<common::dataStructures::TapeLog> RdbmsCatalogue::getTapeLogFromRset(con } } -//------------------------------------------------------------------------------ -// reclaimTape -//------------------------------------------------------------------------------ -void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) { - throw exception::Exception(std::string(__FUNCTION__) + " not implemented"); -} - //------------------------------------------------------------------------------ // modifyTapeLogicalLibraryName //------------------------------------------------------------------------------ diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index a858fb57ab..674348f4d1 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -67,7 +67,7 @@ public: /** * Destructor. */ - virtual ~RdbmsCatalogue() override; + ~RdbmsCatalogue() override; ///////////////////////////////////////////////////////////////////// // START OF METHODS DIRECTLY INVOLVED IN DATA TRANSFER AND SCHEDULING @@ -80,7 +80,7 @@ public: * @param drive The name of tape drive that was used to label the tape. * @param lbpIsOn Set to true if Logical Block Protection (LBP) was enabled. */ - virtual void tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) override; + void tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) override; /** * Prepares the catalogue for a new archive file and returns the information @@ -97,7 +97,7 @@ public: * archiving the file. * @return The information required to queue the associated archive request. */ - virtual common::dataStructures::ArchiveFileQueueCriteria prepareForNewFile( + common::dataStructures::ArchiveFileQueueCriteria prepareForNewFile( const std::string &diskInstanceName, const std::string &storageClassName, const common::dataStructures::UserIdentity &user) override; @@ -109,14 +109,14 @@ public: * * @param logicalLibraryName The name of the logical library. */ - virtual std::list<TapeForWriting> getTapesForWriting(const std::string &logicalLibraryName) const override; + std::list<TapeForWriting> getTapesForWriting(const std::string &logicalLibraryName) const override; /** * Notifies the catalogue that a file has been written to tape. * * @param event The tape file written event. */ - virtual void fileWrittenToTape(const TapeFileWritten &event) override; + void fileWrittenToTape(const TapeFileWritten &event) override; /** * Notifies the CTA catalogue that the specified tape has been mounted in @@ -128,7 +128,7 @@ public: * @param vid The volume identifier of the tape. * @param drive The name of the drive where the tape was mounted. */ - virtual void tapeMountedForArchive(const std::string &vid, const std::string &drive) override; + void tapeMountedForArchive(const std::string &vid, const std::string &drive) override; /** * Prepares for a file retrieval by returning the information required to @@ -143,7 +143,7 @@ public: * * @return The information required to queue the associated retrieve request(s). */ - virtual common::dataStructures::RetrieveFileQueueCriteria prepareToRetrieveFile( + common::dataStructures::RetrieveFileQueueCriteria prepareToRetrieveFile( const std::string &instanceName, const uint64_t archiveFileId, const common::dataStructures::UserIdentity &user) override; @@ -158,7 +158,7 @@ public: * @param vid The volume identifier of the tape. * @param drive The name of the drive where the tape was mounted. */ - virtual void tapeMountedForRetrieve(const std::string &vid, const std::string &drive) override; + void tapeMountedForRetrieve(const std::string &vid, const std::string &drive) override; /** * This method notifies the CTA catalogue that there is no more free space on @@ -166,23 +166,23 @@ public: * * @param vid The volume identifier of the tape. */ - virtual void noSpaceLeftOnTape(const std::string &vid) override; + void noSpaceLeftOnTape(const std::string &vid) override; /////////////////////////////////////////////////////////////////// // END OF METHODS DIRECTLY INVOLVED IN DATA TRANSFER AND SCHEDULING /////////////////////////////////////////////////////////////////// - virtual void createBootstrapAdminAndHostNoAuth(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &hostName, const std::string &comment) override; + void createBootstrapAdminAndHostNoAuth(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &hostName, const std::string &comment) override; - virtual void createAdminUser(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &comment) override; - virtual void deleteAdminUser(const std::string &username) override; - virtual std::list<common::dataStructures::AdminUser> getAdminUsers() const override; - virtual void modifyAdminUserComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &comment) override; + void createAdminUser(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &comment) override; + void deleteAdminUser(const std::string &username) override; + std::list<common::dataStructures::AdminUser> getAdminUsers() const override; + void modifyAdminUserComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &username, const std::string &comment) override; - virtual void createAdminHost(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &hostName, const std::string &comment) override; - virtual void deleteAdminHost(const std::string &hostName) override; - virtual std::list<common::dataStructures::AdminHost> getAdminHosts() const override; - virtual void modifyAdminHostComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &hostName, const std::string &comment) override; + void createAdminHost(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &hostName, const std::string &comment) override; + void deleteAdminHost(const std::string &hostName) override; + std::list<common::dataStructures::AdminHost> getAdminHosts() const override; + void modifyAdminHostComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &hostName, const std::string &comment) override; /** * Creates the specified storage class. @@ -190,7 +190,7 @@ public: * @param cliIdentity The identity of the command-line interface. * @param storageClass The storage class. */ - virtual void createStorageClass( + void createStorageClass( const common::dataStructures::SecurityIdentity &cliIdentity, const common::dataStructures::StorageClass &storageClass) override; @@ -202,20 +202,20 @@ public: * @param stoargeClassName The name of the storage class which is only * guaranteed to be unique within its disk isntance. */ - virtual void deleteStorageClass(const std::string &diskInstanceName, const std::string &storageClassName) override; + void deleteStorageClass(const std::string &diskInstanceName, const std::string &storageClassName) override; - virtual std::list<common::dataStructures::StorageClass> getStorageClasses() const override; - virtual void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) override; - virtual void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &name, const std::string &comment) override; + std::list<common::dataStructures::StorageClass> getStorageClasses() const override; + void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) override; + void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &name, const std::string &comment) override; - virtual void createTapePool(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string &comment) override; - virtual void deleteTapePool(const std::string &name) override; - virtual std::list<common::dataStructures::TapePool> getTapePools() const override; - virtual void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes) override; - virtual void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; - virtual void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const bool encryptionValue) override; + void createTapePool(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string &comment) override; + void deleteTapePool(const std::string &name) override; + std::list<common::dataStructures::TapePool> getTapePools() const override; + void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes) override; + void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; + void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const bool encryptionValue) override; - virtual void createArchiveRoute( + void createArchiveRoute( const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &diskInstanceName, const std::string &storageClassName, @@ -233,19 +233,19 @@ public: * guaranteed to be unique within its disk instance. * @param copyNb The copy number of the tape file. */ - virtual void deleteArchiveRoute( + void deleteArchiveRoute( const std::string &diskInstanceName, const std::string &storageClassName, const uint64_t copyNb) override; - virtual std::list<common::dataStructures::ArchiveRoute> getArchiveRoutes() const override; - virtual void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &storageClassName, const uint64_t copyNb, const std::string &tapePoolName) override; - virtual void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &storageClassName, const uint64_t copyNb, const std::string &comment) override; + std::list<common::dataStructures::ArchiveRoute> getArchiveRoutes() const override; + void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &storageClassName, const uint64_t copyNb, const std::string &tapePoolName) override; + void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &storageClassName, const uint64_t copyNb, const std::string &comment) override; - virtual void createLogicalLibrary(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; - virtual void deleteLogicalLibrary(const std::string &name) override; - virtual std::list<common::dataStructures::LogicalLibrary> getLogicalLibraries() const override; - virtual void modifyLogicalLibraryComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; + void createLogicalLibrary(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; + void deleteLogicalLibrary(const std::string &name) override; + std::list<common::dataStructures::LogicalLibrary> getLogicalLibraries() const override; + void modifyLogicalLibraryComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; /** * Creates a tape. @@ -254,7 +254,7 @@ public: * optional parameter should either have a non-empty string value or no value * at all. Empty strings are prohibited. */ - virtual void createTape( + void createTape( const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &logicalLibraryName, @@ -265,7 +265,7 @@ public: const bool full, const std::string &comment) override; - virtual void deleteTape(const std::string &vid) override; + void deleteTape(const std::string &vid) override; /** * Returns the list of tapes that meet the specified search criteria. @@ -273,7 +273,7 @@ public: * @param searchCriteria The search criteria. * @return The list of tapes. */ - virtual std::list<common::dataStructures::Tape> getTapes(const TapeSearchCriteria &searchCriteria) const override; + std::list<common::dataStructures::Tape> getTapes(const TapeSearchCriteria &searchCriteria) const override; /** * Returns the tapes with the specified volume identifiers. @@ -284,13 +284,27 @@ public: * @param vids The tape volume identifiers (VIDs). * @return Map from tape volume identifier to tape. */ - virtual common::dataStructures::VidToTapeMap getTapesByVid(const std::set<std::string> &vids) const override; + common::dataStructures::VidToTapeMap getTapesByVid(const std::set<std::string> &vids) const override; - virtual void reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) override; - virtual void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &logicalLibraryName) override; - virtual void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &tapePoolName) override; - virtual void modifyTapeCapacityInBytes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const uint64_t capacityInBytes) override; - virtual void modifyTapeEncryptionKey(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &encryptionKey) override; + /** + * Reclaims the specified tape. + * + * This method will throw an exception if the specified tape does not exist. + * + * This method will throw an exception if the specified tape is not FULL. + * + * This method will throw an exception if there is still at least one tape + * file recorded in the cataligue as being on the specified tape. + * + * @param cliIdentity The user of the command-line tool. + * @param vid The volume identifier of the tape to be reclaimed. + */ + void reclaimTape(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid) override; + + void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &logicalLibraryName) override; + void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &tapePoolName) override; + void modifyTapeCapacityInBytes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const uint64_t capacityInBytes) override; + void modifyTapeEncryptionKey(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &encryptionKey) override; /** * Sets the full status of the specified tape. @@ -302,17 +316,17 @@ public: * @param vid The volume identifier of the tape to be marked as full. * @param fullValue Set to true if the tape is full. */ - virtual void setTapeFull(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool fullValue) override; + void setTapeFull(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool fullValue) override; - virtual void setTapeDisabled(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool disabledValue) override; - virtual void modifyTapeComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &comment) override; + void setTapeDisabled(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool disabledValue) override; + void modifyTapeComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const std::string &comment) override; - virtual void modifyRequesterMountRulePolicy(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterName, const std::string &mountPolicy) override; - virtual void modifyRequesteMountRuleComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterName, const std::string &comment) override; - virtual void modifyRequesterGroupMountRulePolicy(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterGroupName, const std::string &mountPolicy) override; - virtual void modifyRequesterGroupMountRuleComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterGroupName, const std::string &comment) override; + void modifyRequesterMountRulePolicy(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterName, const std::string &mountPolicy) override; + void modifyRequesteMountRuleComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterName, const std::string &comment) override; + void modifyRequesterGroupMountRulePolicy(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterGroupName, const std::string &mountPolicy) override; + void modifyRequesterGroupMountRuleComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &instanceName, const std::string &requesterGroupName, const std::string &comment) override; - virtual void createMountPolicy( + void createMountPolicy( const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t archivePriority, @@ -327,14 +341,14 @@ public: * * @return the list of all existing mount policies. */ - virtual std::list<common::dataStructures::MountPolicy> getMountPolicies() const override; + std::list<common::dataStructures::MountPolicy> getMountPolicies() const override; /** * Deletes the specified mount policy. * * @param name The name of the mount policy. */ - virtual void deleteMountPolicy(const std::string &name) override; + void deleteMountPolicy(const std::string &name) override; /** * Creates the rule that the specified mount policy will be used for the @@ -351,7 +365,7 @@ public: * be unique within its disk instance. * @param comment Comment. */ - virtual void createRequesterMountRule( + void createRequesterMountRule( const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &mountPolicyName, const std::string &diskInstance, @@ -365,7 +379,7 @@ public: * @return the rules that specify which mount policy is be used for which * requester. */ - virtual std::list<common::dataStructures::RequesterMountRule> getRequesterMountRules() const override; + std::list<common::dataStructures::RequesterMountRule> getRequesterMountRules() const override; /** * Deletes the specified mount rule. @@ -375,7 +389,7 @@ public: * @param requesterName The name of the requester which is only guaranteed to * be unique within its disk instance. */ - virtual void deleteRequesterMountRule(const std::string &diskInstanceName, const std::string &requesterName) override; + void deleteRequesterMountRule(const std::string &diskInstanceName, const std::string &requesterName) override; /** * Creates the rule that the specified mount policy will be used for the @@ -392,7 +406,7 @@ public: * guarantted to be unique within its disk instance. * @param comment Comment. */ - virtual void createRequesterGroupMountRule( + void createRequesterGroupMountRule( const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &mountPolicyName, const std::string &diskInstanceName, @@ -406,7 +420,7 @@ public: * @return the rules that specify which mount policy is be used for which * requester group. */ - virtual std::list<common::dataStructures::RequesterGroupMountRule> getRequesterGroupMountRules() const override; + std::list<common::dataStructures::RequesterGroupMountRule> getRequesterGroupMountRules() const override; /** * Deletes the specified mount rule. @@ -416,27 +430,27 @@ public: * @param requesterGroupName The name of the requester group which is only * guaranteed to be unique within its disk instance. */ - virtual void deleteRequesterGroupMountRule( + void deleteRequesterGroupMountRule( const std::string &diskInstanceName, const std::string &requesterGroupName) override; - virtual void modifyMountPolicyArchivePriority(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t archivePriority) override; - virtual void modifyMountPolicyArchiveMinRequestAge(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t minArchiveRequestAge) override; - virtual void modifyMountPolicyRetrievePriority(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t retrievePriority) override; - virtual void modifyMountPolicyRetrieveMinRequestAge(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t minRetrieveRequestAge) override; - virtual void modifyMountPolicyMaxDrivesAllowed(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t maxDrivesAllowed) override; - virtual void modifyMountPolicyComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; - - virtual void createDedication(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const common::dataStructures::DedicationType dedicationType, - const optional<std::string> &tag, const optional<std::string> &vid, const uint64_t fromTimestamp, const uint64_t untilTimestamp,const std::string &comment) override; - virtual void deleteDedication(const std::string &drivename) override; - virtual std::list<common::dataStructures::Dedication> getDedications() const override; - virtual void modifyDedicationType(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const common::dataStructures::DedicationType dedicationType) override; - virtual void modifyDedicationTag(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const optional<std::string> &tag) override; - virtual void modifyDedicationVid(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const optional<std::string> &vid) override; - virtual void modifyDedicationFrom(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const uint64_t fromTimestamp) override; - virtual void modifyDedicationUntil(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const uint64_t untilTimestamp) override; - virtual void modifyDedicationComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const std::string &comment) override; + void modifyMountPolicyArchivePriority(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t archivePriority) override; + void modifyMountPolicyArchiveMinRequestAge(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t minArchiveRequestAge) override; + void modifyMountPolicyRetrievePriority(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t retrievePriority) override; + void modifyMountPolicyRetrieveMinRequestAge(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t minRetrieveRequestAge) override; + void modifyMountPolicyMaxDrivesAllowed(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t maxDrivesAllowed) override; + void modifyMountPolicyComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) override; + + void createDedication(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const common::dataStructures::DedicationType dedicationType, + const optional<std::string> &tag, const optional<std::string> &vid, const uint64_t fromTimestamp, const uint64_t untilTimestamp,const std::string &comment) override; + void deleteDedication(const std::string &drivename) override; + std::list<common::dataStructures::Dedication> getDedications() const override; + void modifyDedicationType(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const common::dataStructures::DedicationType dedicationType) override; + void modifyDedicationTag(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const optional<std::string> &tag) override; + void modifyDedicationVid(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const optional<std::string> &vid) override; + void modifyDedicationFrom(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const uint64_t fromTimestamp) override; + void modifyDedicationUntil(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const uint64_t untilTimestamp) override; + void modifyDedicationComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &drivename, const std::string &comment) override; /** * Returns an iterator over the list of archive files that meet the specified @@ -453,7 +467,7 @@ public: * This parameter must be set to a value equal to or greater than 1. * @return An iterator over the list of archive files. */ - virtual std::unique_ptr<ArchiveFileItor> getArchiveFileItor(const ArchiveFileSearchCriteria &searchCriteria, + std::unique_ptr<ArchiveFileItor> getArchiveFileItor(const ArchiveFileSearchCriteria &searchCriteria, const uint64_t nbArchiveFilesToPrefetch) const override; /** @@ -463,7 +477,7 @@ public: * @param searchCriteria The search criteria. * @return The summary. */ - virtual common::dataStructures::ArchiveFileSummary getArchiveFileSummary( + common::dataStructures::ArchiveFileSummary getArchiveFileSummary( const ArchiveFileSearchCriteria &searchCriteria) const override; /** @@ -475,7 +489,7 @@ public: * @param id The unique identifier of the archive file. * @return The archive file. */ - virtual common::dataStructures::ArchiveFile getArchiveFileById(const uint64_t id) override; + common::dataStructures::ArchiveFile getArchiveFileById(const uint64_t id) override; /** * Returns true if the specified user running the CTA command-line tool on @@ -486,7 +500,7 @@ public: * @return True if the specified user running the CTA command-line tool on * the specified host has administrator privileges. */ - virtual bool isAdmin(const common::dataStructures::SecurityIdentity &cliIdentity) const override; + bool isAdmin(const common::dataStructures::SecurityIdentity &cliIdentity) const override; protected: @@ -552,6 +566,15 @@ protected: */ bool tapeExists(rdbms::Conn &conn, const std::string &vid) const; + /** + * Returns the list of tapes that meet the specified search criteria. + * + * @param conn The database connection. + * @param searchCriteria The search criteria. + * @return The list of tapes. + */ + std::list<common::dataStructures::Tape> getTapes(rdbms::Conn &conn, const TapeSearchCriteria &searchCriteria) const; + /** * Returns true if the specified logical library exists. * @@ -813,17 +836,17 @@ protected: /** * Destructor. */ - virtual ~ArchiveFileItorImpl() override; + ~ArchiveFileItorImpl() override; /** * Returns true if a call to next would return another archive file. */ - virtual bool hasMore() const override; + bool hasMore() const override; /** * Returns the next archive or throws an exception if there isn't one. */ - virtual common::dataStructures::ArchiveFile next() override; + common::dataStructures::ArchiveFile next() override; private: @@ -882,7 +905,7 @@ protected: * @return The mapping from tape copy to tape pool for the specified storage * class. */ - virtual common::dataStructures::TapeCopyToPoolMap getTapeCopyToPoolMap( + common::dataStructures::TapeCopyToPoolMap getTapeCopyToPoolMap( rdbms::Conn &conn, const std::string &diskInstanceName, const std::string &storageClassName) const; diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp index 8d330bf18a..db1cb7fee6 100644 --- a/catalogue/SqliteCatalogue.hpp +++ b/catalogue/SqliteCatalogue.hpp @@ -44,7 +44,7 @@ public: /** * Destructor. */ - virtual ~SqliteCatalogue() override; + ~SqliteCatalogue() override; /** * Deletes the specified archive file and its associated tape copies from the @@ -59,7 +59,7 @@ public: * @return The metadata of the deleted archive file including the metadata of * the associated and also deleted tape copies. */ - virtual common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName, + common::dataStructures::ArchiveFile deleteArchiveFile(const std::string &diskInstanceName, const uint64_t archiveFileId) override; protected: -- GitLab