diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 8078e285195e49fc055908bf8f3089fd5d700c86..2157c4853d687434849aeacd8b122f81ba1d63c4 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -46,6 +46,7 @@ #include "common/dataStructures/RepackInfo.hpp" #include "common/dataStructures/RepackType.hpp" #include "common/dataStructures/Requester.hpp" +#include "common/dataStructures/RetrieveFileQueueCriteria.hpp" #include "common/dataStructures/RetrieveJob.hpp" #include "common/dataStructures/RetrieveRequest.hpp" #include "common/dataStructures/SecurityIdentity.hpp" @@ -210,9 +211,9 @@ public: * archiving the file. * @return The information required to queue the associated archive request. */ - virtual common::dataStructures::ArchiveFileQueueCriteria - prepareForNewFile(const std::string &storageClass, const common::dataStructures::UserIdentity &user) - = 0; + virtual common::dataStructures::ArchiveFileQueueCriteria prepareForNewFile( + const std::string &storageClass, + const common::dataStructures::UserIdentity &user) = 0; /** * Notifies the catalogue that a file has been written to tape. @@ -221,6 +222,22 @@ public: */ virtual void fileWrittenToTape(const TapeFileWritten &event) = 0; + /** + * Prepares for a file retrieval by returning the information required to + * queue the associated retrieve request(s). + * + * @param archiveFileId The unique identifier of the archived file that is + * to be retrieved. + * @param user The user for whom the file is to be retrieved. This will be + * used by the Catalogue to determine the mount policy to be used when + * retrieving the file. + * + * @return The information required to queue the associated retrieve request(s). + */ + virtual common::dataStructures::RetrieveFileQueueCriteria prepareToRetrieveFile( + const uint64_t archiveFileId, + common::dataStructures::UserIdentity &user) = 0; + virtual common::dataStructures::TapeCopyToPoolMap getTapeCopyToPoolMap(const std::string &storageClass) const = 0; /** diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index e580d7cc2e0c0954b948e5c5fcc7b1cbc48918c1..cb9a1f96be0be31bfcd739e443df21952b73875c 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -1895,106 +1895,6 @@ void RdbmsCatalogue::setDriveStatus(const common::dataStructures::SecurityIdenti throw exception::Exception(std::string(__FUNCTION__) + " not implemented"); } -//------------------------------------------------------------------------------ -// fileWrittenToTape -//------------------------------------------------------------------------------ -void RdbmsCatalogue::fileWrittenToTape(const TapeFileWritten &event) { - try { - const time_t now = time(NULL); - std::lock_guard<std::mutex> m_lock(m_mutex); - - std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile = getArchiveFile(event.archiveFileId); - - // If the archive file does not already exist - if(NULL == archiveFile.get()) { - // Create one - ArchiveFileRow row; - row.archiveFileId = event.archiveFileId; - row.diskFileId = event.diskFileId; - row.diskInstance = event.diskInstance; - row.size = event.size; - row.storageClassName = event.storageClassName; - row.diskFilePath = event.diskFilePath; - row.diskFileUser = event.diskFileUser; - row.diskFileGroup = event.diskFileGroup; - row.diskFileRecoveryBlob = event.diskFileRecoveryBlob; - insertArchiveFile(row); - } else { - throwIfCommonEventDataMismatch(*archiveFile, event); - } - - // Create the tape file - common::dataStructures::TapeFile tapeFile; - tapeFile.vid = event.vid; - tapeFile.fSeq = event.fSeq; - tapeFile.blockId = event.blockId; - tapeFile.compressedSize = event.compressedSize; - tapeFile.copyNb = event.copyNb; - tapeFile.creationTime = now; - createTapeFile(tapeFile, event.archiveFileId); - } catch(exception::Exception &ex) { - exception::Exception ex; - ex.getMessage() << __FUNCTION__ << " failed: " << ex.getMessage().str(); - throw ex; - } -} - -//------------------------------------------------------------------------------ -// throwIfCommonEventDataMismatch -//------------------------------------------------------------------------------ -void RdbmsCatalogue::throwIfCommonEventDataMismatch(const common::dataStructures::ArchiveFile &expected, - const TapeFileWritten &actual) const { - // Throw an exception if the common disk information of this tape file - // written event does not match the previous - if(expected.diskFileID != actual.diskFileId) { - exception::Exception ex; - ex.getMessage() << "Disk file ID mismatch: expected=" << expected.diskFileID << " actual=" << - actual.diskFileId; - throw ex; - } - if(expected.fileSize != actual.size) { - exception::Exception ex; - ex.getMessage() << "File size mismatch: expected=" << expected.fileSize << " actual=" << actual.size; - throw ex; - } - if(expected.storageClass != actual.storageClassName) { - exception::Exception ex; - ex.getMessage() << "Storage class mismatch: expected=" << expected.storageClass << " actual=" << - actual.storageClassName; - throw ex; - } - if(expected.diskInstance != actual.diskInstance) { - exception::Exception ex; - ex.getMessage() << "Disk instance mismatch: expected=" << expected.diskInstance << " actual=" << - actual.diskInstance; - throw ex; - } - if(expected.drData.drPath != actual.diskFilePath) { - exception::Exception ex; - ex.getMessage() << "Disk file path mismatch: expected=" << expected.drData.drPath << " actual=" << - actual.diskFilePath; - throw ex; - } - if(expected.drData.drOwner != actual.diskFileUser) { - exception::Exception ex; - ex.getMessage() << "Disk file user mismatch: expected=" << expected.drData.drOwner << " actual=" << - actual.diskFileUser; - throw ex; - } - if(expected.drData.drGroup != actual.diskFileGroup) { - exception::Exception ex; - ex.getMessage() << "Disk file group mismatch: expected=" << expected.drData.drGroup << " actual=" << - actual.diskFileGroup; - throw ex; - } - if(expected.drData.drGroup != actual.diskFileGroup) { - exception::Exception ex; - ex.getMessage() << "Disk recovery blob mismatch"; - throw ex; - } - -} - //------------------------------------------------------------------------------ // prepareForNewFile //------------------------------------------------------------------------------ @@ -2161,6 +2061,115 @@ common::dataStructures::MountPolicy RdbmsCatalogue:: } } +//------------------------------------------------------------------------------ +// fileWrittenToTape +//------------------------------------------------------------------------------ +void RdbmsCatalogue::fileWrittenToTape(const TapeFileWritten &event) { + try { + const time_t now = time(NULL); + std::lock_guard<std::mutex> m_lock(m_mutex); + + std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile = getArchiveFile(event.archiveFileId); + + // If the archive file does not already exist + if(NULL == archiveFile.get()) { + // Create one + ArchiveFileRow row; + row.archiveFileId = event.archiveFileId; + row.diskFileId = event.diskFileId; + row.diskInstance = event.diskInstance; + row.size = event.size; + row.storageClassName = event.storageClassName; + row.diskFilePath = event.diskFilePath; + row.diskFileUser = event.diskFileUser; + row.diskFileGroup = event.diskFileGroup; + row.diskFileRecoveryBlob = event.diskFileRecoveryBlob; + insertArchiveFile(row); + } else { + throwIfCommonEventDataMismatch(*archiveFile, event); + } + + // Create the tape file + common::dataStructures::TapeFile tapeFile; + tapeFile.vid = event.vid; + tapeFile.fSeq = event.fSeq; + tapeFile.blockId = event.blockId; + tapeFile.compressedSize = event.compressedSize; + tapeFile.copyNb = event.copyNb; + tapeFile.creationTime = now; + createTapeFile(tapeFile, event.archiveFileId); + } catch(exception::Exception &ex) { + exception::Exception ex; + ex.getMessage() << __FUNCTION__ << " failed: " << ex.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// throwIfCommonEventDataMismatch +//------------------------------------------------------------------------------ +void RdbmsCatalogue::throwIfCommonEventDataMismatch(const common::dataStructures::ArchiveFile &expected, + const TapeFileWritten &actual) const { + // Throw an exception if the common disk information of this tape file + // written event does not match the previous + if(expected.diskFileID != actual.diskFileId) { + exception::Exception ex; + ex.getMessage() << "Disk file ID mismatch: expected=" << expected.diskFileID << " actual=" << + actual.diskFileId; + throw ex; + } + if(expected.fileSize != actual.size) { + exception::Exception ex; + ex.getMessage() << "File size mismatch: expected=" << expected.fileSize << " actual=" << actual.size; + throw ex; + } + if(expected.storageClass != actual.storageClassName) { + exception::Exception ex; + ex.getMessage() << "Storage class mismatch: expected=" << expected.storageClass << " actual=" << + actual.storageClassName; + throw ex; + } + if(expected.diskInstance != actual.diskInstance) { + exception::Exception ex; + ex.getMessage() << "Disk instance mismatch: expected=" << expected.diskInstance << " actual=" << + actual.diskInstance; + throw ex; + } + if(expected.drData.drPath != actual.diskFilePath) { + exception::Exception ex; + ex.getMessage() << "Disk file path mismatch: expected=" << expected.drData.drPath << " actual=" << + actual.diskFilePath; + throw ex; + } + if(expected.drData.drOwner != actual.diskFileUser) { + exception::Exception ex; + ex.getMessage() << "Disk file user mismatch: expected=" << expected.drData.drOwner << " actual=" << + actual.diskFileUser; + throw ex; + } + if(expected.drData.drGroup != actual.diskFileGroup) { + exception::Exception ex; + ex.getMessage() << "Disk file group mismatch: expected=" << expected.drData.drGroup << " actual=" << + actual.diskFileGroup; + throw ex; + } + if(expected.drData.drGroup != actual.diskFileGroup) { + exception::Exception ex; + ex.getMessage() << "Disk recovery blob mismatch"; + throw ex; + } + +} + +//------------------------------------------------------------------------------ +// prepareToRetreiveFile +//------------------------------------------------------------------------------ +common::dataStructures::RetrieveFileQueueCriteria RdbmsCatalogue::prepareToRetrieveFile( + const uint64_t archiveFileId, + common::dataStructures::UserIdentity &user) { + throw exception::Exception(std::string(__FUNCTION__) + " not implemented"); +} + //------------------------------------------------------------------------------ // isAdmin //------------------------------------------------------------------------------ diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index 8d42907b11f80adeb2d930156c1c1fd9a6c3ece1..38279046747b1a00ca7b91a31e27704e978ece2d 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -176,14 +176,6 @@ public: virtual common::dataStructures::ArchiveFile getArchiveFileById(const uint64_t id); virtual void setDriveStatus(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &driveName, const bool up, const bool force); - - /** - * Notifies the catalogue that a file has been written to tape. - * - * @param event The tape file written event. - */ - virtual void fileWrittenToTape(const TapeFileWritten &event); - /** * Prepares the catalogue for a new archive file and returns the information * required to queue the associated archive request. @@ -196,8 +188,32 @@ public: * archiving the file. * @return The information required to queue the associated archive request. */ - virtual common::dataStructures::ArchiveFileQueueCriteria - prepareForNewFile(const std::string &storageClass, const common::dataStructures::UserIdentity &user); + virtual common::dataStructures::ArchiveFileQueueCriteria prepareForNewFile( + const std::string &storageClass, + const common::dataStructures::UserIdentity &user); + + /** + * Notifies the catalogue that a file has been written to tape. + * + * @param event The tape file written event. + */ + virtual void fileWrittenToTape(const TapeFileWritten &event); + + /** + * Prepares for a file retrieval by returning the information required to + * queue the associated retrieve request(s). + * + * @param archiveFileId The unique identifier of the archived file that is + * to be retrieved. + * @param user The user for whom the file is to be retrieved. This will be + * used by the Catalogue to determine the mount policy to be used when + * retrieving the file. + * + * @return The information required to queue the associated retrieve request(s). + */ + virtual common::dataStructures::RetrieveFileQueueCriteria prepareToRetrieveFile( + const uint64_t archiveFileId, + common::dataStructures::UserIdentity &user); virtual common::dataStructures::TapeCopyToPoolMap getTapeCopyToPoolMap(const std::string &storageClass) const; diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 42d49912e812e6987cbdee9c05223d88d464f5fa..562576cfbd96c0a332fee7e13773762097a8f96c 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -46,6 +46,7 @@ set (COMMON_LIB_SRC_FILES dataStructures/RepackInfo.cpp dataStructures/RepackType.cpp dataStructures/Requester.cpp + dataStructures/RetrieveFileQueueCriteria.cpp dataStructures/RetrieveJob.cpp dataStructures/RetrieveRequest.cpp dataStructures/SecurityIdentity.cpp