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

Added unit-test deleteArchiveFile_of_another_disk_instance

parent 4e1d5bd7
......@@ -495,6 +495,10 @@ public:
* Deletes the specified archive file and its associated tape copies from the
* catalogue.
*
* Please note that the name of the disk instance is specified in order to
* prevent a disk instance deleting an archive file that belongs to another
* disk instance.
*
* @param instanceName The name of the instance from where the deletion request originated
* @param archiveFileId The unique identifier of the archive file.
* @return The metadata of the deleted archive file including the metadata of
......
......@@ -6062,6 +6062,319 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
ASSERT_FALSE(m_catalogue->getArchiveFileItor()->hasMore());
}
TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_of_another_disk_instance) {
using namespace cta;
const std::string vid1 = "VID123";
const std::string vid2 = "VID456";
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, vid1, logicalLibraryName, tapePoolName,
encryptionKey, capacityInBytes, disabledValue, fullValue,
comment);
m_catalogue->createTape(m_cliSI, vid2, logicalLibraryName, tapePoolName,
encryptionKey, capacityInBytes, disabledValue, fullValue,
comment);
{
const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes();
ASSERT_EQ(2, tapes.size());
const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes);
{
auto it = vidToTape.find(vid1);
const common::dataStructures::Tape &tape = it->second;
ASSERT_EQ(vid1, tape.vid);
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);
}
{
auto it = vidToTape.find(vid2);
const common::dataStructures::Tape &tape = it->second;
ASSERT_EQ(vid2, tape.vid);
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);
}
}
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 = "disk_instance";
storageClass.name = "storage_class";
storageClass.nbCopies = 2;
storageClass.comment = "Create storage class";
m_catalogue->createStorageClass(m_cliSI, storageClass);
const uint64_t archiveFileSize = 1;
const std::string checksumType = "checksum_type";
const std::string checksumValue = "checksum_value";
const std::string tapeDrive = "tape_drive";
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);
{
catalogue::TapeSearchCriteria searchCriteria;
searchCriteria.vid = file1Written.vid;
std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(searchCriteria);
ASSERT_EQ(1, tapes.size());
const common::dataStructures::Tape &tape = tapes.front();
ASSERT_EQ(1, tape.lastFSeq);
}
{
std::unique_ptr<catalogue::ArchiveFileItor> archiveFileItor = m_catalogue->getArchiveFileItor();
const std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(*archiveFileItor);
ASSERT_EQ(1, m.size());
auto mItor = m.find(file1Written.archiveFileId);
ASSERT_FALSE(m.end() == mItor);
const common::dataStructures::ArchiveFile archiveFile = mItor->second;
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 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);
}
catalogue::TapeFileWritten file2Written;
file2Written.archiveFileId = file1Written.archiveFileId;
file2Written.diskInstance = file1Written.diskInstance;
file2Written.diskFileId = file1Written.diskFileId;
file2Written.diskFilePath = file1Written.diskFilePath;
file2Written.diskFileUser = file1Written.diskFileUser;
file2Written.diskFileGroup = file1Written.diskFileGroup;
file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
file2Written.size = archiveFileSize;
file2Written.checksumType = checksumType;
file2Written.checksumValue = checksumValue;
file2Written.storageClassName = storageClass.name;
file2Written.vid = vid2;
file2Written.fSeq = 1;
file2Written.blockId = 4331;
file2Written.compressedSize = 1;
file2Written.copyNb = 2;
file2Written.tapeDrive = tapeDrive;
m_catalogue->fileWrittenToTape(file2Written);
{
ASSERT_EQ(2, m_catalogue->getTapes().size());
catalogue::TapeSearchCriteria searchCriteria;
searchCriteria.vid = file2Written.vid;
std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(searchCriteria);
ASSERT_EQ(1, tapes.size());
const common::dataStructures::Tape &tape = tapes.front();
ASSERT_EQ(1, tape.lastFSeq);
}
{
std::unique_ptr<catalogue::ArchiveFileItor> archiveFileItor = m_catalogue->getArchiveFileItor();
const std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(*archiveFileItor);
ASSERT_EQ(1, m.size());
{
auto mItor = m.find(file1Written.archiveFileId);
ASSERT_FALSE(m.end() == mItor);
const common::dataStructures::ArchiveFile archiveFile = mItor->second;
ASSERT_EQ(file2Written.archiveFileId, archiveFile.archiveFileID);
ASSERT_EQ(file2Written.diskFileId, archiveFile.diskFileId);
ASSERT_EQ(file2Written.size, archiveFile.fileSize);
ASSERT_EQ(file2Written.checksumType, archiveFile.checksumType);
ASSERT_EQ(file2Written.checksumValue, archiveFile.checksumValue);
ASSERT_EQ(file2Written.storageClassName, archiveFile.storageClass);
ASSERT_EQ(file2Written.diskInstance, archiveFile.diskInstance);
ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
ASSERT_EQ(2, 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);
auto copyNbToTapeFile2Itor = archiveFile.tapeFiles.find(2);
ASSERT_FALSE(copyNbToTapeFile2Itor == archiveFile.tapeFiles.end());
const common::dataStructures::TapeFile &tapeFile2 = copyNbToTapeFile2Itor->second;
ASSERT_EQ(file2Written.vid, tapeFile2.vid);
ASSERT_EQ(file2Written.fSeq, tapeFile2.fSeq);
ASSERT_EQ(file2Written.blockId, tapeFile2.blockId);
ASSERT_EQ(file2Written.compressedSize, tapeFile2.compressedSize);
ASSERT_EQ(file2Written.checksumType, tapeFile2.checksumType);
ASSERT_EQ(file2Written.checksumValue, tapeFile2.checksumValue);
ASSERT_EQ(file2Written.copyNb, tapeFile2.copyNb);
}
}
{
const common::dataStructures::ArchiveFile archiveFile = m_catalogue->getArchiveFileById(archiveFileId);
ASSERT_EQ(file2Written.archiveFileId, archiveFile.archiveFileID);
ASSERT_EQ(file2Written.diskFileId, archiveFile.diskFileId);
ASSERT_EQ(file2Written.size, archiveFile.fileSize);
ASSERT_EQ(file2Written.checksumType, archiveFile.checksumType);
ASSERT_EQ(file2Written.checksumValue, archiveFile.checksumValue);
ASSERT_EQ(file2Written.storageClassName, archiveFile.storageClass);
ASSERT_EQ(file2Written.diskInstance, archiveFile.diskInstance);
ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
ASSERT_EQ(2, 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);
auto copyNbToTapeFile2Itor = archiveFile.tapeFiles.find(2);
ASSERT_FALSE(copyNbToTapeFile2Itor == archiveFile.tapeFiles.end());
const common::dataStructures::TapeFile &tapeFile2 = copyNbToTapeFile2Itor->second;
ASSERT_EQ(file2Written.vid, tapeFile2.vid);
ASSERT_EQ(file2Written.fSeq, tapeFile2.fSeq);
ASSERT_EQ(file2Written.blockId, tapeFile2.blockId);
ASSERT_EQ(file2Written.compressedSize, tapeFile2.compressedSize);
ASSERT_EQ(file2Written.checksumType, tapeFile2.checksumType);
ASSERT_EQ(file2Written.checksumValue, tapeFile2.checksumValue);
ASSERT_EQ(file2Written.copyNb, tapeFile2.copyNb);
}
ASSERT_THROW(m_catalogue->deleteArchiveFile("another_disk_instance", archiveFileId), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_non_existant) {
using namespace cta;
......
......@@ -127,6 +127,15 @@ common::dataStructures::ArchiveFile OracleCatalogue::deleteArchiveFile(
throw ue;
}
if(diskInstanceName != archiveFile->diskInstance) {
exception::UserError ue;
ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because the disk instance of "
"the request does not match that of the archived file: archiveFileId=" << archiveFileId << " path=" <<
archiveFile->diskFileInfo.path << " requestDiskInstance=" << diskInstanceName << " archiveFileDiskInstance=" <<
archiveFile->diskInstance;
throw ue;
}
{
const char *const sql = "DELETE FROM TAPE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::OFF);
......
......@@ -55,6 +55,10 @@ public:
* Deletes the specified archive file and its associated tape copies from the
* catalogue.
*
* Please note that the name of the disk instance is specified in order to
* prevent a disk instance deleting an archive file that belongs to another
* disk instance.
*
* @param instanceName The name of the instance from where the deletion request originated
* @param archiveFileId The unique identifier of the archive file.
* @return The metadata of the deleted archive file including the metadata of
......
......@@ -3512,16 +3512,16 @@ common::dataStructures::ArchiveFileSummary RdbmsCatalogue::getArchiveFileSummary
common::dataStructures::ArchiveFile RdbmsCatalogue::getArchiveFileById(const uint64_t id) {
try {
auto conn = m_connPool.getConn();
std::unique_ptr<common::dataStructures::ArchiveFile> file(getArchiveFile(*conn, id));
std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile(getArchiveFile(*conn, id));
// Throw an exception if the archive file does not exist
if(nullptr == file.get()) {
if(nullptr == archiveFile.get()) {
exception::Exception ex;
ex.getMessage() << "No such archive file with ID " << id;
throw (ex);
}
return *file;
return *archiveFile;
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
......
......@@ -48,75 +48,9 @@ SqliteCatalogue::~SqliteCatalogue() {
//------------------------------------------------------------------------------
common::dataStructures::ArchiveFile SqliteCatalogue::deleteArchiveFile(const std::string &diskInstanceName, const uint64_t archiveFileId) {
try {
std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile;
auto conn = m_connPool.getConn();
rdbms::AutoRollback autoRollback(conn.get());
const char *selectSql =
"SELECT "
"ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID,"
"ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME,"
"ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID,"
"ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
"ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
"ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
"ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
"ARCHIVE_FILE.FILE_SIZE AS FILE_SIZE,"
"ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
"ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
"ARCHIVE_FILE.STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
"ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME,"
"ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME,"
"TAPE_FILE.VID AS VID,"
"TAPE_FILE.FSEQ AS FSEQ,"
"TAPE_FILE.BLOCK_ID AS BLOCK_ID,"
"TAPE_FILE.COMPRESSED_SIZE AS COMPRESSED_SIZE,"
"TAPE_FILE.COPY_NB AS COPY_NB,"
"TAPE_FILE.CREATION_TIME AS TAPE_FILE_CREATION_TIME "
"FROM "
"ARCHIVE_FILE "
"LEFT OUTER JOIN TAPE_FILE ON "
"ARCHIVE_FILE.ARCHIVE_FILE_ID = TAPE_FILE.ARCHIVE_FILE_ID "
"WHERE "
"ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
auto selectStmt = conn->createStmt(selectSql, rdbms::Stmt::AutocommitMode::OFF);
selectStmt->bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
std::unique_ptr<rdbms::Rset> selectRset(selectStmt->executeQuery());
while(selectRset->next()) {
if(nullptr == archiveFile.get()) {
archiveFile = cta::make_unique<common::dataStructures::ArchiveFile>();
archiveFile->archiveFileID = selectRset->columnUint64("ARCHIVE_FILE_ID");
archiveFile->diskInstance = selectRset->columnString("DISK_INSTANCE_NAME");
archiveFile->diskFileId = selectRset->columnString("DISK_FILE_ID");
archiveFile->diskFileInfo.path = selectRset->columnString("DISK_FILE_PATH");
archiveFile->diskFileInfo.owner = selectRset->columnString("DISK_FILE_USER");
archiveFile->diskFileInfo.group = selectRset->columnString("DISK_FILE_GROUP");
archiveFile->diskFileInfo.recoveryBlob = selectRset->columnString("DISK_FILE_RECOVERY_BLOB");
archiveFile->fileSize = selectRset->columnUint64("FILE_SIZE");
archiveFile->checksumType = selectRset->columnString("CHECKSUM_TYPE");
archiveFile->checksumValue = selectRset->columnString("CHECKSUM_VALUE");
archiveFile->storageClass = selectRset->columnString("STORAGE_CLASS_NAME");
archiveFile->creationTime = selectRset->columnUint64("ARCHIVE_FILE_CREATION_TIME");
archiveFile->reconciliationTime = selectRset->columnUint64("RECONCILIATION_TIME");
}
// If there is a tape file
if(!selectRset->columnIsNull("VID")) {
// Add the tape file to the archive file's in-memory structure
common::dataStructures::TapeFile tapeFile;
tapeFile.vid = selectRset->columnString("VID");
tapeFile.fSeq = selectRset->columnUint64("FSEQ");
tapeFile.blockId = selectRset->columnUint64("BLOCK_ID");
tapeFile.compressedSize = selectRset->columnUint64("COMPRESSED_SIZE");
tapeFile.copyNb = selectRset->columnUint64("COPY_NB");
tapeFile.creationTime = selectRset->columnUint64("TAPE_FILE_CREATION_TIME");
tapeFile.checksumType = archiveFile->checksumType; // Duplicated for convenience
tapeFile.checksumValue = archiveFile->checksumValue; // Duplicated for convenience
archiveFile->tapeFiles[selectRset->columnUint64("COPY_NB")] = tapeFile;
}
}
const auto archiveFile = getArchiveFile(*conn, archiveFileId);
if(nullptr == archiveFile.get()) {
exception::UserError ue;
......@@ -124,6 +58,15 @@ common::dataStructures::ArchiveFile SqliteCatalogue::deleteArchiveFile(const std
throw ue;
}
if(diskInstanceName != archiveFile->diskInstance) {
exception::UserError ue;
ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because the disk instance of "
"the request does not match that of the archived file: archiveFileId=" << archiveFileId << " path=" <<
archiveFile->diskFileInfo.path << " requestDiskInstance=" << diskInstanceName << " archiveFileDiskInstance=" <<
archiveFile->diskInstance;
throw ue;
}
{
const char *const sql = "DELETE FROM TAPE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID;";
auto stmt = conn->createStmt(sql, rdbms::Stmt::AutocommitMode::OFF);
......
......@@ -50,6 +50,10 @@ public:
* Deletes the specified archive file and its associated tape copies from the
* catalogue.
*
* Please note that the name of the disk instance is specified in order to
* prevent a disk instance deleting an archive file that belongs to another
* disk instance.
*
* @param instanceName The name of the instance from where the deletion request originated
* @param archiveFileId The unique identifier of the archive file.
* @return The metadata of the deleted archive file including the metadata of
......
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