From 8380d4b381d4c6f7dbb429aba4c84b25d6fe0353 Mon Sep 17 00:00:00 2001 From: Cedric CAFFY <cedric.caffy@cern.ch> Date: Wed, 4 Mar 2020 10:13:01 +0100 Subject: [PATCH] Implemented Catalogue::createVirtualOrganization() + unit tests --- catalogue/Catalogue.hpp | 8 ++ catalogue/CatalogueRetryWrapper.hpp | 6 +- catalogue/CatalogueTest.cpp | 39 ++++++++ catalogue/DummyCatalogue.hpp | 2 + catalogue/MysqlCatalogue.cpp | 42 +++++++++ catalogue/MysqlCatalogue.hpp | 14 +++ catalogue/OracleCatalogue.cpp | 25 +++++ catalogue/OracleCatalogue.hpp | 14 +++ catalogue/PostgresCatalogue.cpp | 20 ++++ catalogue/PostgresCatalogue.hpp | 14 +++ catalogue/RdbmsCatalogue.cpp | 94 +++++++++++++++++++ catalogue/RdbmsCatalogue.hpp | 29 ++++++ catalogue/SqliteCatalogue.cpp | 29 ++++++ catalogue/SqliteCatalogue.hpp | 14 +++ common/CMakeLists.txt | 1 + common/dataStructures/VirtualOrganization.cpp | 19 ++++ common/dataStructures/VirtualOrganization.hpp | 40 ++++++++ 17 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 common/dataStructures/VirtualOrganization.cpp create mode 100644 common/dataStructures/VirtualOrganization.hpp diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index b76a9d0abd..1e0b4613de 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -53,6 +53,7 @@ #include "common/dataStructures/TapeFile.hpp" #include "common/dataStructures/UpdateFileInfoRequest.hpp" #include "common/dataStructures/RequesterIdentity.hpp" +#include "common/dataStructures/VirtualOrganization.hpp" #include "common/dataStructures/VidToTapeMap.hpp" #include "common/dataStructures/WriteTestResult.hpp" #include "disk/DiskSystem.hpp" @@ -225,6 +226,13 @@ public: virtual std::list<common::dataStructures::AdminUser> getAdminUsers() const = 0; virtual void modifyAdminUserComment(const common::dataStructures::SecurityIdentity &admin, const std::string &username, const std::string &comment) = 0; + /** + * Creates the specified Virtual Organization + * @param admin The administrator. + * @param vo the Virtual Organization + */ + virtual void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) = 0; + /** * Creates the specified storage class. * diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index 57d023c857..b82233e422 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -115,7 +115,11 @@ public: void modifyAdminUserComment(const common::dataStructures::SecurityIdentity &admin, const std::string &username, const std::string &comment) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyAdminUserComment(admin, username, comment);}, m_maxTriesToConnect); } - + + void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->createVirtualOrganization(admin, vo);}, m_maxTriesToConnect); + } + void createStorageClass(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::StorageClass &storageClass) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->createStorageClass(admin, storageClass);}, m_maxTriesToConnect); } diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index 9ae8ead02c..e5d5897e9f 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -15286,4 +15286,43 @@ TEST_P(cta_catalogue_CatalogueTest, getSchemaVersion) { ASSERT_EQ((uint64_t)CTA_CATALOGUE_SCHEMA_VERSION_MINOR,schemaDbVersion.getSchemaVersion<catalogue::SchemaVersion::MajorMinor>().second); } +TEST_P(cta_catalogue_CatalogueTest, createVirtualOrganization) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo; + vo.name = "VO"; + vo.comment = "Comment"; + + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); +} + +TEST_P(cta_catalogue_CatalogueTest, createVirtualOrganizationAlreadyExists) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo; + vo.name = "VO"; + vo.comment = "Comment"; + + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); + ASSERT_THROW(m_catalogue->createVirtualOrganization(m_admin,vo),cta::exception::UserError); +} + +TEST_P(cta_catalogue_CatalogueTest, createVirtualOrganizationEmptyComment) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo; + vo.name = "VO"; + + ASSERT_THROW(m_catalogue->createVirtualOrganization(m_admin,vo),cta::exception::UserError); +} + +TEST_P(cta_catalogue_CatalogueTest, createVirtualOrganizationEmptyName) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo; + vo.comment = "comment"; + + ASSERT_THROW(m_catalogue->createVirtualOrganization(m_admin,vo),cta::exception::UserError); +} + } // namespace unitTests diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index 7572c9b944..c2cff5b265 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -87,6 +87,8 @@ public: bool isAdmin(const common::dataStructures::SecurityIdentity& admin) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyActivitiesFairShareWeight(const common::dataStructures::SecurityIdentity& admin, const std::string& diskInstanceName, const std::string& acttivity, double weight, const std::string & comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyAdminUserComment(const common::dataStructures::SecurityIdentity& admin, const std::string& username, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + + void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyLogicalLibraryName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tName, const std::string &newName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } diff --git a/catalogue/MysqlCatalogue.cpp b/catalogue/MysqlCatalogue.cpp index cec4378fca..a7470bec28 100644 --- a/catalogue/MysqlCatalogue.cpp +++ b/catalogue/MysqlCatalogue.cpp @@ -137,6 +137,48 @@ uint64_t MysqlCatalogue::getNextLogicalLibraryId(rdbms::Conn &conn) { } } +//------------------------------------------------------------------------------ +// getNextVirtualOrganizationId +//------------------------------------------------------------------------------ +uint64_t MysqlCatalogue::getNextVirtualOrganizationId(rdbms::Conn& conn) { + try { + rdbms::AutoRollback autoRollback(conn); + + conn.executeNonQuery("START TRANSACTION"); + + { + const char *const sql = + "UPDATE VIRTUAL_ORGANIZATION_ID SET ID = LAST_INSERT_ID(ID + 1)"; + auto stmt = conn.createStmt(sql); + stmt.executeNonQuery(); + } + + uint64_t virtualOrganizationId = 0; + { + const char *const sql = + "SELECT LAST_INSERT_ID() AS ID "; + auto stmt = conn.createStmt(sql); + auto rset = stmt.executeQuery(); + if(!rset.next()) { + throw exception::Exception("VIRTUAL_ORGANIZATION_ID table is empty"); + } + virtualOrganizationId = rset.columnUint64("ID"); + if(rset.next()) { + throw exception::Exception("Found more than one ID counter in the VIRTUAL_ORGANIZATION_ID table"); + } + } + conn.commit(); + + return virtualOrganizationId; + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + //------------------------------------------------------------------------------ // getNextStorageClassId //------------------------------------------------------------------------------ diff --git a/catalogue/MysqlCatalogue.hpp b/catalogue/MysqlCatalogue.hpp index 4781b4dc3c..211cb387d0 100644 --- a/catalogue/MysqlCatalogue.hpp +++ b/catalogue/MysqlCatalogue.hpp @@ -84,6 +84,20 @@ protected: * library storage class within the catalogue. */ uint64_t getNextLogicalLibraryId(rdbms::Conn &conn) override; + + /** + * Returns a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + * + * This method must be implemented by the sub-classes of RdbmsCatalogue + * because different database technologies propose different solution to the + * problem of generating ever increasing numeric identifiers. + * + * @param conn The database connection + * @return a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + */ + uint64_t getNextVirtualOrganizationId(rdbms::Conn &conn) override; /** * Returns a unique storage class ID that can be used by a new storage class diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp index 79509a6917..2c33efd6a9 100644 --- a/catalogue/OracleCatalogue.cpp +++ b/catalogue/OracleCatalogue.cpp @@ -202,6 +202,31 @@ uint64_t OracleCatalogue::getNextLogicalLibraryId(rdbms::Conn &conn) { } } +//------------------------------------------------------------------------------ +// getNextVirtualOrganizationId +//------------------------------------------------------------------------------ +uint64_t OracleCatalogue::getNextVirtualOrganizationId(rdbms::Conn &conn) { + try { + const char *const sql = + "SELECT " + "VIRTUAL_ORGANIZATION_ID_SEQ.NEXTVAL AS VIRTUAL_ORGANIZATION_ID " + "FROM " + "DUAL"; + auto stmt = conn.createStmt(sql); + auto rset = stmt.executeQuery(); + if (!rset.next()) { + throw exception::Exception(std::string("Result set is unexpectedly empty")); + } + + return rset.columnUint64("VIRTUAL_ORGANIZATION_ID"); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // getNextStorageClassId //------------------------------------------------------------------------------ diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp index 730b63b77c..3d4efbdf8f 100644 --- a/catalogue/OracleCatalogue.hpp +++ b/catalogue/OracleCatalogue.hpp @@ -84,6 +84,20 @@ public: * library storage class within the catalogue. */ uint64_t getNextLogicalLibraryId(rdbms::Conn &conn) override; + + /** + * Returns a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + * + * This method must be implemented by the sub-classes of RdbmsCatalogue + * because different database technologies propose different solution to the + * problem of generating ever increasing numeric identifiers. + * + * @param conn The database connection + * @return a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + */ + uint64_t getNextVirtualOrganizationId(rdbms::Conn &conn) override; /** * Returns a unique storage class ID that can be used by a new storage class diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp index c2b41457ba..c8ed6c7ccd 100644 --- a/catalogue/PostgresCatalogue.cpp +++ b/catalogue/PostgresCatalogue.cpp @@ -192,6 +192,26 @@ uint64_t PostgresCatalogue::getNextLogicalLibraryId(rdbms::Conn &conn) { } } +//------------------------------------------------------------------------------ +// getNextVirtualOrganizationId +//------------------------------------------------------------------------------ +uint64_t PostgresCatalogue::getNextVirtualOrganizationId(rdbms::Conn &conn) { + try { + const char *const sql = + "select NEXTVAL('VIRTUAL_ORGANIZATION_ID_SEQ') AS VIRTUAL_ORGANIZATION_ID"; + auto stmt = conn.createStmt(sql); + auto rset = stmt.executeQuery(); + if(!rset.next()) { + throw exception::Exception("Result set is unexpectedly empty"); + } + return rset.columnUint64("VIRTUAL_ORGANIZATION_ID"); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} //------------------------------------------------------------------------------ // getNextStorageClassId //------------------------------------------------------------------------------ diff --git a/catalogue/PostgresCatalogue.hpp b/catalogue/PostgresCatalogue.hpp index 085e4a0695..6db30ef340 100644 --- a/catalogue/PostgresCatalogue.hpp +++ b/catalogue/PostgresCatalogue.hpp @@ -111,6 +111,20 @@ public: */ uint64_t getNextLogicalLibraryId(rdbms::Conn &conn) override; + /** + * Returns a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + * + * This method must be implemented by the sub-classes of RdbmsCatalogue + * because different database technologies propose different solution to the + * problem of generating ever increasing numeric identifiers. + * + * @param conn The database connection + * @return a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + */ + uint64_t getNextVirtualOrganizationId(rdbms::Conn &conn) override; + /** * Returns a unique storage class ID that can be used by a new storage class * within the catalogue. diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index 5d00c3f6ac..37f4cf8bad 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -186,6 +186,30 @@ bool RdbmsCatalogue::adminUserExists(rdbms::Conn &conn, const std::string adminU } } +//------------------------------------------------------------------------------ +// virtualOrganizationExists +//------------------------------------------------------------------------------ +bool RdbmsCatalogue::virtualOrganizationExists(rdbms::Conn &conn, const std::string &voName) const { + try { + const char *const sql = + "SELECT " + "VIRTUAL_ORGANIZATION_NAME AS VIRTUAL_ORGANIZATION_NAME " + "FROM " + "VIRTUAL_ORGANIZATION " + "WHERE " + "VIRTUAL_ORGANIZATION_NAME = :VIRTUAL_ORGANIZATION_NAME"; + auto stmt = conn.createStmt(sql); + stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", voName); + auto rset = stmt.executeQuery(); + return rset.next(); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // deleteAdminUser //------------------------------------------------------------------------------ @@ -301,6 +325,76 @@ void RdbmsCatalogue::modifyAdminUserComment(const common::dataStructures::Securi } } +//------------------------------------------------------------------------------ +// createVirtualOrganization +//------------------------------------------------------------------------------ +void RdbmsCatalogue::createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo){ + try{ + if(vo.name.empty()){ + throw UserSpecifiedAnEmptyStringVo("Cannot create virtual organization because the name is an empty string"); + } + if(vo.comment.empty()) { + throw UserSpecifiedAnEmptyStringComment("Cannot create virtual organization because the comment is an empty string"); + } + auto conn = m_connPool.getConn(); + if(virtualOrganizationExists(conn, vo.name)) { + throw exception::UserError(std::string("Cannot create vo : ") + + vo.name + " because it already exists"); + } + const uint64_t virtualOrganizationId = getNextVirtualOrganizationId(conn); + const time_t now = time(nullptr); + const char *const sql = + "INSERT INTO VIRTUAL_ORGANIZATION(" + "VIRTUAL_ORGANIZATION_ID," + "VIRTUAL_ORGANIZATION_NAME," + + "USER_COMMENT," + + "CREATION_LOG_USER_NAME," + "CREATION_LOG_HOST_NAME," + "CREATION_LOG_TIME," + + "LAST_UPDATE_USER_NAME," + "LAST_UPDATE_HOST_NAME," + "LAST_UPDATE_TIME)" + "VALUES(" + ":VIRTUAL_ORGANIZATION_ID," + ":VIRTUAL_ORGANIZATION_NAME," + + ":USER_COMMENT," + + ":CREATION_LOG_USER_NAME," + ":CREATION_LOG_HOST_NAME," + ":CREATION_LOG_TIME," + + ":LAST_UPDATE_USER_NAME," + ":LAST_UPDATE_HOST_NAME," + ":LAST_UPDATE_TIME)"; + auto stmt = conn.createStmt(sql); + + stmt.bindUint64(":VIRTUAL_ORGANIZATION_ID", virtualOrganizationId); + stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", vo.name); + + stmt.bindString(":USER_COMMENT", vo.comment); + + stmt.bindString(":CREATION_LOG_USER_NAME", admin.username); + stmt.bindString(":CREATION_LOG_HOST_NAME", admin.host); + stmt.bindUint64(":CREATION_LOG_TIME", now); + + stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username); + stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host); + stmt.bindUint64(":LAST_UPDATE_TIME", now); + + stmt.executeNonQuery(); + + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // createStorageClass //------------------------------------------------------------------------------ diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index d7f8f4a1cd..7fbbf3d241 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -211,6 +211,13 @@ public: void deleteAdminUser(const std::string &username) override; std::list<common::dataStructures::AdminUser> getAdminUsers() const override; void modifyAdminUserComment(const common::dataStructures::SecurityIdentity &admin, const std::string &username, const std::string &comment) override; + + /** + * Creates the specified Virtual Organization + * @param admin The administrator. + * @param vo the Virtual Organization + */ + void createVirtualOrganization(const common::dataStructures::SecurityIdentity &admin, const common::dataStructures::VirtualOrganization &vo) override; /** * Creates the specified storage class. @@ -802,6 +809,14 @@ protected: */ bool adminUserExists(rdbms::Conn &conn, const std::string adminUsername) const; + /** + * Returns true if the specified vo exists. + * + * @param conn The database connection. + * @param voName The name of the vo + * @return True if the vo exists, false otherwise + */ + bool virtualOrganizationExists(rdbms::Conn &conn, const std::string &voName) const; /** * Returns true if the specified storage class exists. * @@ -1388,6 +1403,20 @@ protected: */ virtual uint64_t getNextLogicalLibraryId(rdbms::Conn &conn) = 0; + /** + * Returns a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + * + * This method must be implemented by the sub-classes of RdbmsCatalogue + * because different database technologies propose different solution to the + * problem of generating ever increasing numeric identifiers. + * + * @param conn The database connection + * @return a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + */ + virtual uint64_t getNextVirtualOrganizationId(rdbms::Conn &conn) = 0; + /** * Returns a unique storage class ID that can be used by a new storage class * within the catalogue. diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp index 3d4ad28874..9a65f42aa2 100644 --- a/catalogue/SqliteCatalogue.cpp +++ b/catalogue/SqliteCatalogue.cpp @@ -252,6 +252,35 @@ uint64_t SqliteCatalogue::getNextLogicalLibraryId(rdbms::Conn &conn) { } } +//------------------------------------------------------------------------------ +// getNextVirtualOrganizationId +//------------------------------------------------------------------------------ +uint64_t SqliteCatalogue::getNextVirtualOrganizationId(rdbms::Conn &conn) { +try { + conn.executeNonQuery("INSERT INTO VIRTUAL_ORGANIZATION_ID VALUES(NULL)"); + uint64_t virtualOrganizationId = 0; + { + const char *const sql = "SELECT LAST_INSERT_ROWID() AS ID"; + auto stmt = conn.createStmt(sql); + auto rset = stmt.executeQuery(); + if(!rset.next()) { + throw exception::Exception(std::string("Unexpected empty result set for '") + sql + "\'"); + } + virtualOrganizationId = rset.columnUint64("ID"); + if(rset.next()) { + throw exception::Exception(std::string("Unexpectedly found more than one row in the result of '") + sql + "\'"); + } + } + conn.executeNonQuery("DELETE FROM VIRTUAL_ORGANIZATION_ID"); + + return virtualOrganizationId; + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} //------------------------------------------------------------------------------ // getNextStorageClassId //------------------------------------------------------------------------------ diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp index 73589a0370..205d82769b 100644 --- a/catalogue/SqliteCatalogue.hpp +++ b/catalogue/SqliteCatalogue.hpp @@ -113,6 +113,20 @@ protected: * library storage class within the catalogue. */ uint64_t getNextLogicalLibraryId(rdbms::Conn &conn) override; + + /** + * Returns a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + * + * This method must be implemented by the sub-classes of RdbmsCatalogue + * because different database technologies propose different solution to the + * problem of generating ever increasing numeric identifiers. + * + * @param conn The database connection + * @return a unique virtual organization ID that can be used by a new Virtual Organization + * within the catalogue. + */ + uint64_t getNextVirtualOrganizationId(rdbms::Conn &conn) override; /** * Returns a unique storage class ID that can be used by a new storage class diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f1063e5b02..c574437654 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -73,6 +73,7 @@ set (COMMON_LIB_SRC_FILES dataStructures/TestSourceType.cpp dataStructures/UpdateFileInfoRequest.cpp dataStructures/UpdateFileStorageClassRequest.cpp + dataStructures/VirtualOrganization.cpp dataStructures/WriteTestResult.cpp dataStructures/utils.cpp checksum/ChecksumBlob.cpp diff --git a/common/dataStructures/VirtualOrganization.cpp b/common/dataStructures/VirtualOrganization.cpp new file mode 100644 index 0000000000..13141a50b7 --- /dev/null +++ b/common/dataStructures/VirtualOrganization.cpp @@ -0,0 +1,19 @@ +/** + * The CERN Tape Archive (CTA) project + * Copyright © 2018 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "VirtualOrganization.hpp" diff --git a/common/dataStructures/VirtualOrganization.hpp b/common/dataStructures/VirtualOrganization.hpp new file mode 100644 index 0000000000..07c2440130 --- /dev/null +++ b/common/dataStructures/VirtualOrganization.hpp @@ -0,0 +1,40 @@ +/** + * The CERN Tape Archive (CTA) project + * Copyright © 2018 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <string> + +namespace cta { +namespace common { +namespace dataStructures { + +struct VirtualOrganization { + /** + * The name + */ + std::string name; + /** + * The comment. + */ + std::string comment; +}; + +}}} + + -- GitLab