diff --git a/libs/client/CMakeLists.txt b/libs/client/CMakeLists.txt index 0af157fac054e0a4b82e4ba02cae00aba412ca3f..6912da86d8ce816d80084b8cddf0281cde13c678 100644 --- a/libs/client/CMakeLists.txt +++ b/libs/client/CMakeLists.txt @@ -10,6 +10,7 @@ set (CLIENT_LIB_SRC_FILES FileSystemNode.cpp FileSystemStorageClass.cpp FileSystemStorageClasses.cpp + MigrationRoute.cpp MockClientAPI.cpp SecurityIdentity.cpp StorageClass.cpp diff --git a/libs/client/ClientAPI.hpp b/libs/client/ClientAPI.hpp index b11f2a4c78f50e9e0d8c88d40b1e94c1a91c4e2a..ee7b2cdc68dbd2700f6e1ca568a3001c5d1e1f22 100644 --- a/libs/client/ClientAPI.hpp +++ b/libs/client/ClientAPI.hpp @@ -1,6 +1,7 @@ #pragma once #include "DirectoryIterator.hpp" +#include "MigrationRoute.hpp" #include "SecurityIdentity.hpp" #include "StorageClass.hpp" #include "TapePool.hpp" @@ -153,6 +154,46 @@ public: virtual std::list<TapePool> getTapePools( const SecurityIdentity &requester) const = 0; + /** + * Creates the specified migration route. + * + * @param requester The identity of the user requesting the creation of the + * migration route. + * @param storageClassName The name of the storage class that identifies the + * source disk files. + * @param copyNb The tape copy number. + * @param tapePoolName The name of the destination tape pool. + * @param comment The comment describing the migration roue. + */ + virtual void createMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb, + const std::string &tapePoolName, + const std::string &comment) = 0; + + /** + * Deletes the specified migration route. + * + * @param requester The identity of the user requesting the deletion of the + * migration route. + * @param storageClassName The name of the storage class that identifies the + * source disk files. + * @param copyNb The tape copy number. + */ + virtual void deleteMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb) = 0; + + /** + * Gets the current list of migration routes. + * + * @param requester The identity of the user requesting the list. + */ + virtual std::list<MigrationRoute> getMigrationRoutes( + const SecurityIdentity &requester) const = 0; + /** * Creates the specified directory. * diff --git a/libs/client/DirectoryEntry.hpp b/libs/client/DirectoryEntry.hpp index 5c0707e0e98c36c6270ac111d446698f6dda7103..b45463e42a8f92268c2c3174f52fbf257057f027 100644 --- a/libs/client/DirectoryEntry.hpp +++ b/libs/client/DirectoryEntry.hpp @@ -68,14 +68,14 @@ public: uint32_t getOwnerId() const throw(); /** - * Returns The group ID of the directory entry. + * Returns the group ID of the directory entry. * * @return The group ID of the directory entry. */ uint32_t getGroupId() const throw(); /** - * Returns The mode bits of the directory entry. + * Returns the mode bits of the directory entry. * * @return The mode bits of the directory entry. */ @@ -130,6 +130,6 @@ private: */ std::string m_storageClassName; -}; // DirectoryEntry +}; // class DirectoryEntry } // namespace cta diff --git a/libs/client/MigrationRoute.cpp b/libs/client/MigrationRoute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6706cac94f3842a79a6d3c15a2604dbe850ff2b8 --- /dev/null +++ b/libs/client/MigrationRoute.cpp @@ -0,0 +1,61 @@ +#include "MigrationRoute.hpp" + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +cta::MigrationRoute::MigrationRoute(): + m_copyNb(0), + m_creationTime(time(NULL)) { +} + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +cta::MigrationRoute::MigrationRoute( + const std::string &storageClassName, + const uint8_t copyNb, + const std::string &tapePoolName, + const UserIdentity &creator, + const std::string &comment): + m_storageClassName(storageClassName), + m_copyNb(copyNb), + m_tapePoolName(tapePoolName), + m_creationTime(time(NULL)), + m_creator(creator), + m_comment(comment) { +} + +//------------------------------------------------------------------------------ +// getStorageClassName +//------------------------------------------------------------------------------ +const std::string &cta::MigrationRoute::getStorageClassName() const throw() { + return m_storageClassName; +} + +//------------------------------------------------------------------------------ +// getCopyNb +//------------------------------------------------------------------------------ +uint8_t cta::MigrationRoute::getCopyNb() const throw() { + return m_copyNb; +} + +//------------------------------------------------------------------------------ +// getTapePoolName +//------------------------------------------------------------------------------ +const std::string &cta::MigrationRoute::getTapePoolName() const throw() { + return m_tapePoolName; +} + +//------------------------------------------------------------------------------ +// getCreator +//------------------------------------------------------------------------------ +const cta::UserIdentity &cta::MigrationRoute::getCreator() const throw() { + return m_creator; +} + +//------------------------------------------------------------------------------ +// getComment +//------------------------------------------------------------------------------ +const std::string &cta::MigrationRoute::getComment() const throw() { + return m_comment; +} diff --git a/libs/client/MigrationRoute.hpp b/libs/client/MigrationRoute.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d54569c691a2126d54461e9157cf85c8aee40fc9 --- /dev/null +++ b/libs/client/MigrationRoute.hpp @@ -0,0 +1,110 @@ +#pragma once + +#include "UserIdentity.hpp" + +#include <stdint.h> +#include <string> +#include <time.h> + +namespace cta { + +/** + * A migration route. + */ +class MigrationRoute { +public: + + /** + * Constructor. + */ + MigrationRoute(); + + /** + * Constructor. + * + * @param storageClassName The name of the storage class that identifies the + * source disk files. + * @param copyNb The tape copy number. + * @param tapePoolName The name of the destination tape pool. + * @param creator The identity of the user that created the storage class. + * @param comment Comment describing the storage class. + */ + MigrationRoute( + const std::string &storageClassName, + const uint8_t copyNb, + const std::string &tapePoolName, + const UserIdentity &creator, + const std::string &comment); + + /** + * Returns the name of the storage class that identifies the source disk + * files. + * + * @return The name of the storage class that identifies the source disk + * files. + */ + const std::string &getStorageClassName() const throw(); + + /** + * Returns the tape copy number. + * + * @return The tape copy number. + */ + uint8_t getCopyNb() const throw(); + + /** + * Returns the name of the destination tape pool. + * + * @return The name of the destination tape pool. + */ + const std::string &getTapePoolName() const throw(); + + /** + * Returns the identity of the user that created the storage class. + * + * @return The identity of the user that created the storage class. + */ + const UserIdentity &getCreator() const throw(); + + /** + * Returns the comment describing the storage class. + * + * @return The comment describing the storage class. + */ + const std::string &getComment() const throw(); + +private: + + /** + * The name of the storage class that identifies the source disk files. + */ + std::string m_storageClassName; + + /** + * The tape copy number. + */ + uint32_t m_copyNb; + + /** + * The name of the destination tape pool. + */ + std::string m_tapePoolName; + + /** + * The time when the storage class was created. + */ + time_t m_creationTime; + + /** + * The identity of the user that created the storage class. + */ + UserIdentity m_creator; + + /** + * Comment describing the storage class. + */ + std::string m_comment; + +}; // class MigrationRoute + +} // namespace cta diff --git a/libs/client/MockClientAPI.cpp b/libs/client/MockClientAPI.cpp index 339ce10dda16cfdb7f360938b8d7c0a933f02986..2de846ad65595fe909b50e5e1b2c605281e63bf7 100644 --- a/libs/client/MockClientAPI.cpp +++ b/libs/client/MockClientAPI.cpp @@ -202,6 +202,35 @@ std::list<cta::TapePool> cta::MockClientAPI::getTapePools( return tapePools; } +//------------------------------------------------------------------------------ +// createMigrationRoute +//------------------------------------------------------------------------------ +void cta::MockClientAPI::createMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb, + const std::string &tapePoolName, + const std::string &comment) { +} + +//------------------------------------------------------------------------------ +// deleteMigrationRoute +//------------------------------------------------------------------------------ +void cta::MockClientAPI::deleteMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb) { +} + +//------------------------------------------------------------------------------ +// getMigrationRoutes +//------------------------------------------------------------------------------ +std::list<cta::MigrationRoute> cta::MockClientAPI::getMigrationRoutes( + const SecurityIdentity &requester) const { + std::list<MigrationRoute> migrationRoutes; + return migrationRoutes; +} + //------------------------------------------------------------------------------ // createDirectory //------------------------------------------------------------------------------ diff --git a/libs/client/MockClientAPI.hpp b/libs/client/MockClientAPI.hpp index 0ac86088a0414fdfdd6b6f830f5d40cb85bfff31..61727b61a7ccdc5fba55c01b3cc6e654d8755238 100644 --- a/libs/client/MockClientAPI.hpp +++ b/libs/client/MockClientAPI.hpp @@ -155,6 +155,46 @@ public: std::list<TapePool> getTapePools( const SecurityIdentity &requester) const; + /** + * Creates the specified migration route. + * + * @param requester The identity of the user requesting the creation of the + * migration route. + * @param storageClassName The name of the storage class that identifies the + * source disk files. + * @param copyNb The tape copy number. + * @param tapePoolName The name of the destination tape pool. + * @param comment The comment describing the migration roue. + */ + void createMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb, + const std::string &tapePoolName, + const std::string &comment); + + /** + * Deletes the specified migration route. + * + * @param requester The identity of the user requesting the deletion of the + * migration route. + * @param storageClassName The name of the storage class that identifies the + * source disk files. + * @param copyNb The tape copy number. + */ + void deleteMigrationRoute( + const SecurityIdentity &requester, + const std::string &storageClassName, + const uint8_t copyNb); + + /** + * Gets the current list of migration routes. + * + * @param requester The identity of the user requesting the list. + */ + std::list<MigrationRoute> getMigrationRoutes( + const SecurityIdentity &requester) const; + /** * Creates the specified directory. * diff --git a/libs/client/MockClientAPITest.cpp b/libs/client/MockClientAPITest.cpp index df7c20d9b5127792459766c49c179e4d609159e5..41ed704a07cee25db0190890df1712d6c4a806ea 100644 --- a/libs/client/MockClientAPITest.cpp +++ b/libs/client/MockClientAPITest.cpp @@ -599,6 +599,165 @@ TEST_F(cta_client_MockClientAPITest, deleteTapePool_non_existing) { } } +TEST_F(cta_client_MockClientAPITest, createMigrationRoute_new) { + using namespace cta; + + TestingMockClientAPI api; + const SecurityIdentity requester; + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_TRUE(migrationRoutes.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const std::string comment = "Comment"; + { + const uint8_t nbCopies = 2; + ASSERT_NO_THROW(api.createStorageClass(requester, storageClassName, + nbCopies, comment)); + } + + const std::string tapePoolName = "TestTapePool"; + ASSERT_NO_THROW(api.createTapePool(requester, tapePoolName, comment)); + + const uint8_t copyNb = 1; + ASSERT_NO_THROW(api.createMigrationRoute(requester, storageClassName, + copyNb, tapePoolName, comment)); + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_EQ(1, migrationRoutes.size()); + + MigrationRoute migrationRoute; + ASSERT_NO_THROW(migrationRoute = migrationRoutes.front()); + ASSERT_EQ(storageClassName, migrationRoute.getStorageClassName()); + ASSERT_EQ(copyNb, migrationRoute.getCopyNb()); + ASSERT_EQ(tapePoolName, migrationRoute.getTapePoolName()); + } +} + +TEST_F(cta_client_MockClientAPITest, createMigrationRoute_already_existing) { + using namespace cta; + + TestingMockClientAPI api; + const SecurityIdentity requester; + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_TRUE(migrationRoutes.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const std::string comment = "Comment"; + { + const uint8_t nbCopies = 2; + ASSERT_NO_THROW(api.createStorageClass(requester, storageClassName, + nbCopies, comment)); + } + + const std::string tapePoolName = "TestTapePool"; + ASSERT_NO_THROW(api.createTapePool(requester, tapePoolName, comment)); + + const uint8_t copyNb = 1; + ASSERT_NO_THROW(api.createMigrationRoute(requester, storageClassName, + copyNb, tapePoolName, comment)); + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_EQ(1, migrationRoutes.size()); + + MigrationRoute migrationRoute; + ASSERT_NO_THROW(migrationRoute = migrationRoutes.front()); + ASSERT_EQ(storageClassName, migrationRoute.getStorageClassName()); + ASSERT_EQ(copyNb, migrationRoute.getCopyNb()); + ASSERT_EQ(tapePoolName, migrationRoute.getTapePoolName()); + } + + ASSERT_THROW(api.createMigrationRoute(requester, storageClassName, + copyNb, tapePoolName, comment), std::exception); +} + +TEST_F(cta_client_MockClientAPITest, deleteMigrationRoute_existing) { + using namespace cta; + + TestingMockClientAPI api; + const SecurityIdentity requester; + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_TRUE(migrationRoutes.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const std::string comment = "Comment"; + { + const uint8_t nbCopies = 2; + ASSERT_NO_THROW(api.createStorageClass(requester, storageClassName, + nbCopies, comment)); + } + + const std::string tapePoolName = "TestTapePool"; + ASSERT_NO_THROW(api.createTapePool(requester, tapePoolName, comment)); + + const uint8_t copyNb = 1; + ASSERT_NO_THROW(api.createMigrationRoute(requester, storageClassName, + copyNb, tapePoolName, comment)); + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_EQ(1, migrationRoutes.size()); + + MigrationRoute migrationRoute; + ASSERT_NO_THROW(migrationRoute = migrationRoutes.front()); + ASSERT_EQ(storageClassName, migrationRoute.getStorageClassName()); + ASSERT_EQ(copyNb, migrationRoute.getCopyNb()); + ASSERT_EQ(tapePoolName, migrationRoute.getTapePoolName()); + } + + ASSERT_NO_THROW(api.deleteMigrationRoute(requester, storageClassName, + copyNb)); + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_TRUE(migrationRoutes.empty()); + } +} + +TEST_F(cta_client_MockClientAPITest, deleteMigrationRoute_non_existing) { + using namespace cta; + + TestingMockClientAPI api; + const SecurityIdentity requester; + + { + std::list<MigrationRoute> migrationRoutes; + ASSERT_NO_THROW(migrationRoutes = api.getMigrationRoutes(requester)); + ASSERT_TRUE(migrationRoutes.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const std::string comment = "Comment"; + { + const uint8_t nbCopies = 2; + ASSERT_NO_THROW(api.createStorageClass(requester, storageClassName, + nbCopies, comment)); + } + + const std::string tapePoolName = "TestTapePool"; + ASSERT_NO_THROW(api.createTapePool(requester, tapePoolName, comment)); + + const uint8_t copyNb = 1; + ASSERT_NO_THROW(api.deleteMigrationRoute(requester, tapePoolName, copyNb)); +} + TEST_F(cta_client_MockClientAPITest, getDirectoryContents_root_dir_is_empty) { using namespace cta;