Commit 65787c00 authored by Steven Murray's avatar Steven Murray
Browse files

Added new XXXXCatalogueFactory classes and replaced cta-catalogueUnitTests cta-rdbmsUnitTests

parent 8be8b094
...@@ -26,12 +26,19 @@ set (CATALOGUE_LIB_SRC_FILES ...@@ -26,12 +26,19 @@ set (CATALOGUE_LIB_SRC_FILES
ArchiveFileItorImpl.cpp ArchiveFileItorImpl.cpp
Catalogue.cpp Catalogue.cpp
CatalogueFactory.cpp CatalogueFactory.cpp
CatalogueFactoryFactory.cpp
ChecksumTypeMismatch.cpp ChecksumTypeMismatch.cpp
ChecksumValueMismatch.cpp ChecksumValueMismatch.cpp
CmdLineTool.cpp CmdLineTool.cpp
FileSizeMismatch.cpp FileSizeMismatch.cpp
InMemoryCatalogue.cpp InMemoryCatalogue.cpp
InMemoryCatalogueFactory.cpp
MysqlCatalogue.cpp
MysqlCatalogueFactory.cpp
MysqlCatalogueSchema.cpp
OracleCatalogue.cpp OracleCatalogue.cpp
OracleCatalogueFactory.cpp
PostgresqlCatalogueFactory.cpp
SqliteCatalogueSchema.cpp SqliteCatalogueSchema.cpp
TapeFileWritten.cpp TapeFileWritten.cpp
TapeItemImplementation.cpp TapeItemImplementation.cpp
...@@ -40,8 +47,7 @@ set (CATALOGUE_LIB_SRC_FILES ...@@ -40,8 +47,7 @@ set (CATALOGUE_LIB_SRC_FILES
RdbmsCatalogue.cpp RdbmsCatalogue.cpp
SchemaCreatingSqliteCatalogue.cpp SchemaCreatingSqliteCatalogue.cpp
SqliteCatalogue.cpp SqliteCatalogue.cpp
MysqlCatalogue.cpp SqliteCatalogueFactory.cpp
MysqlCatalogueSchema.cpp
TapeForWriting.cpp TapeForWriting.cpp
UserSpecifiedANonEmptyTape.cpp UserSpecifiedANonEmptyTape.cpp
UserSpecifiedANonExistentTape.cpp UserSpecifiedANonExistentTape.cpp
...@@ -123,7 +129,6 @@ add_custom_command(OUTPUT MysqlCatalogueSchema.cpp ...@@ -123,7 +129,6 @@ add_custom_command(OUTPUT MysqlCatalogueSchema.cpp
set(IN_MEMORY_CATALOGUE_UNIT_TESTS_LIB_SRC_FILES set(IN_MEMORY_CATALOGUE_UNIT_TESTS_LIB_SRC_FILES
CatalogueTest.cpp CatalogueTest.cpp
CatalogueFactoryTest.cpp
InMemoryCatalogueTest.cpp InMemoryCatalogueTest.cpp
InMemoryVersionOfCatalogueTest.cpp) InMemoryVersionOfCatalogueTest.cpp)
......
...@@ -17,61 +17,14 @@ ...@@ -17,61 +17,14 @@
*/ */
#include "catalogue/CatalogueFactory.hpp" #include "catalogue/CatalogueFactory.hpp"
#include "catalogue/CatalogueRetryWrapper.hpp"
#include "catalogue/InMemoryCatalogue.hpp"
#include "catalogue/OracleCatalogue.hpp"
#include "catalogue/SqliteCatalogue.hpp"
#include "catalogue/MysqlCatalogue.hpp"
#include "common/exception/Exception.hpp"
#include "common/make_unique.hpp"
namespace cta { namespace cta {
namespace catalogue { namespace catalogue {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// create // destructor
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::unique_ptr<Catalogue> CatalogueFactory::create( CatalogueFactory:: ~CatalogueFactory() {
log::Logger &log,
const rdbms::Login &login,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect) {
try {
switch(login.dbType) {
case rdbms::Login::DBTYPE_IN_MEMORY:
{
auto c = cta::make_unique<InMemoryCatalogue>(log, nbConns, nbArchiveFileListingConns);
return cta::make_unique<CatalogueRetryWrapper>(log, std::move(c), maxTriesToConnect);
}
case rdbms::Login::DBTYPE_ORACLE:
{
auto c = cta::make_unique<OracleCatalogue>(log, login.username, login.password, login.database, nbConns,
nbArchiveFileListingConns);
return cta::make_unique<CatalogueRetryWrapper>(log, std::move(c), maxTriesToConnect);
}
case rdbms::Login::DBTYPE_SQLITE:
{
auto c = cta::make_unique<SqliteCatalogue>(log, login.database, nbConns, nbArchiveFileListingConns);
return cta::make_unique<CatalogueRetryWrapper>(log, std::move(c), maxTriesToConnect);
}
case rdbms::Login::DBTYPE_MYSQL:
{
auto c = cta::make_unique<MysqlCatalogue>(log, login, nbConns, nbArchiveFileListingConns);
return cta::make_unique<CatalogueRetryWrapper>(log, std::move(c), maxTriesToConnect);
}
case rdbms::Login::DBTYPE_NONE:
throw exception::Exception("Cannot create a catalogue without a database type");
default:
{
exception::Exception ex;
ex.getMessage() << "Unknown database type: value=" << login.dbType;
throw ex;
}
}
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
} }
} // namespace catalogue } // namespace catalogue
......
...@@ -19,48 +19,27 @@ ...@@ -19,48 +19,27 @@
#pragma once #pragma once
#include "catalogue/Catalogue.hpp" #include "catalogue/Catalogue.hpp"
#include "rdbms/Login.hpp"
#include <memory> #include <memory>
#include <mutex>
namespace cta { namespace cta {
namespace catalogue { namespace catalogue {
/** /**
* Factory for creating CTA catalogue objects. This class is a singleton. * Specifies the interface to a factory Catalogue objects.
*/ */
class CatalogueFactory { class CatalogueFactory {
public: public:
/** /**
* Prevent objects of this class from being instantiated. * Destructor.
*/ */
CatalogueFactory() = delete; virtual ~CatalogueFactory();
/** /**
* Creates a CTA catalogue object using the specified database login details. * Returns a newly created CTA catalogue object.
*
* @param log Object representing the API to the CTA logging system.
* @param login The database connection details.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
* @return The newly created CTA catalogue object. Please note that it is the
* responsibility of the caller to delete the returned CTA catalogue object.
* @param maxTriesToConnext The maximum number of times a single method should
* try to connect to the database in the event of LostDatabaseConnection
* exceptions being thrown.
*/ */
static std::unique_ptr<Catalogue> create( virtual std::unique_ptr<Catalogue> create() = 0;
log::Logger &log,
const rdbms::Login &login,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect = 3);
}; // class CatalogueFactory }; // class CatalogueFactory
......
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 "catalogue/CatalogueFactoryFactory.hpp"
#include "catalogue/InMemoryCatalogueFactory.hpp"
#include "catalogue/MysqlCatalogueFactory.hpp"
#include "catalogue/OracleCatalogueFactory.hpp"
#include "catalogue/PostgresqlCatalogueFactory.hpp"
#include "catalogue/SqliteCatalogueFactory.hpp"
#include "common/make_unique.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
std::unique_ptr<CatalogueFactory> CatalogueFactoryFactory::create(
log::Logger &log,
const rdbms::Login &login,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect) {
try {
switch(login.dbType) {
case rdbms::Login::DBTYPE_IN_MEMORY:
return cta::make_unique<InMemoryCatalogueFactory>(log, nbConns, nbArchiveFileListingConns, maxTriesToConnect);
case rdbms::Login::DBTYPE_MYSQL:
return cta::make_unique<MysqlCatalogueFactory>(log, login, nbConns, nbArchiveFileListingConns, maxTriesToConnect);
case rdbms::Login::DBTYPE_ORACLE:
return cta::make_unique<OracleCatalogueFactory>(log, login, nbConns, nbArchiveFileListingConns,
maxTriesToConnect);
case rdbms::Login::DBTYPE_POSTGRESQL:
return cta::make_unique<PostgresqlCatalogueFactory>(log, login, nbConns, nbArchiveFileListingConns, maxTriesToConnect);
case rdbms::Login::DBTYPE_SQLITE:
return cta::make_unique<SqliteCatalogueFactory>(log, login, nbConns, nbArchiveFileListingConns, maxTriesToConnect);
case rdbms::Login::DBTYPE_NONE:
throw exception::Exception("Cannot create a catalogue without a database type");
default:
{
exception::Exception ex;
ex.getMessage() << "Unknown database type: value=" << login.dbType;
throw ex;
}
}
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 "catalogue/CatalogueFactory.hpp"
#include "rdbms/Login.hpp"
#include <memory>
namespace cta {
namespace catalogue {
/**
* Factory of catalogue factories. This class is a singleton.
*/
class CatalogueFactoryFactory {
public:
/**
* Prevent objects of this class from being instantiated.
*/
CatalogueFactoryFactory() = delete;
/**
* Creates a factory of CTA catalogue objects using the specified database
* login details.
*
* @param log Object representing the API to the CTA logging system.
* @param login The database connection details.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
* @return The newly created CTA catalogue object. Please note that it is the
* responsibility of the caller to delete the returned CTA catalogue object.
* @param maxTriesToConnext The maximum number of times a single method should
* try to connect to the database in the event of LostDatabaseConnection
* exceptions being thrown.
*/
static std::unique_ptr<CatalogueFactory> create(
log::Logger &log,
const rdbms::Login &login,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect = 3);
}; // class CatalogueFactoryFactory
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 "catalogue/ArchiveFileRow.hpp"
#include "catalogue/CatalogueFactory.hpp"
#include "common/exception/Exception.hpp"
#include "common/log/DummyLogger.hpp"
#include <gtest/gtest.h>
#include <memory>
namespace unitTests {
class cta_catalogue_CatalogueFactoryTest : public ::testing::Test {
public:
cta_catalogue_CatalogueFactoryTest():
m_dummyLog("dummy", "dummy") {
m_localAdmin.username = "local_admin_user";
m_localAdmin.host = "local_admin_host";
m_admin.username = "admin_user";
m_admin.host = "admin_host";
}
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
cta::log::DummyLogger m_dummyLog;
cta::common::dataStructures::SecurityIdentity m_localAdmin;
cta::common::dataStructures::SecurityIdentity m_admin;
};
TEST_F(cta_catalogue_CatalogueFactoryTest, instance_in_memory) {
using namespace cta;
using namespace cta::catalogue;
rdbms::Login login(rdbms::Login::DBTYPE_IN_MEMORY, "", "", "", "", 0);
const uint64_t nbConns = 1;
const uint64_t nbArchiveFileListingConns = 1;
std::unique_ptr<Catalogue> catalogue(CatalogueFactory::create(m_dummyLog, login, nbConns, nbArchiveFileListingConns));
ASSERT_TRUE(nullptr != catalogue.get());
ASSERT_TRUE(catalogue->getAdminUsers().empty());
const std::string createAdminUserComment = "Create admin user";
catalogue->createAdminUser(m_localAdmin, m_admin.username, createAdminUserComment);
{
std::list<common::dataStructures::AdminUser> admins;
admins = catalogue->getAdminUsers();
ASSERT_EQ(1, admins.size());
const common::dataStructures::AdminUser admin = admins.front();
ASSERT_EQ(createAdminUserComment, admin.comment);
const common::dataStructures::EntryLog creationLog = admin.creationLog;
ASSERT_EQ(m_localAdmin.username, creationLog.username);
ASSERT_EQ(m_localAdmin.host, creationLog.host);
const common::dataStructures::EntryLog lastModificationLog = admin.lastModificationLog;
ASSERT_EQ(creationLog, lastModificationLog);
}
}
} // namespace unitTests
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
*/ */
#include "catalogue/ArchiveFileRow.hpp" #include "catalogue/ArchiveFileRow.hpp"
#include "catalogue/CatalogueFactory.hpp"
#include "catalogue/CatalogueTest.hpp" #include "catalogue/CatalogueTest.hpp"
#include "catalogue/ChecksumTypeMismatch.hpp" #include "catalogue/ChecksumTypeMismatch.hpp"
#include "catalogue/ChecksumValueMismatch.hpp" #include "catalogue/ChecksumValueMismatch.hpp"
...@@ -40,6 +39,8 @@ ...@@ -40,6 +39,8 @@
#include "common/exception/UserError.hpp" #include "common/exception/UserError.hpp"
#include "common/make_unique.hpp" #include "common/make_unique.hpp"
#include "rdbms/wrapper/ConnFactoryFactory.hpp" #include "rdbms/wrapper/ConnFactoryFactory.hpp"
#include "rdbms/Conn.hpp"
#include "rdbms/ConnPool.hpp"
#include <algorithm> #include <algorithm>
#include <gtest/gtest.h> #include <gtest/gtest.h>
...@@ -71,13 +72,17 @@ void cta_catalogue_CatalogueTest::SetUp() { ...@@ -71,13 +72,17 @@ void cta_catalogue_CatalogueTest::SetUp() {
using namespace cta::catalogue; using namespace cta::catalogue;
try { try {
const rdbms::Login &login = GetParam()->create(); CatalogueFactory *const *const catalogueFactoryPtrPtr = GetParam();
auto connFactory = rdbms::wrapper::ConnFactoryFactory::create(login);
const uint64_t nbConns = 2;
const uint64_t nbArchiveFileListingConns = 2;
m_catalogue = CatalogueFactory::create(m_dummyLog, login, nbConns, nbArchiveFileListingConns); if(nullptr == catalogueFactoryPtrPtr) {
m_conn = connFactory->create(); throw exception::Exception("Global pointer to the catalogue factory pointer for unit-tests in null");
}
if(nullptr == (*catalogueFactoryPtrPtr)) {
throw exception::Exception("Global pointer to the catalogue factoryfor unit-tests in null");
}
m_catalogue = (*catalogueFactoryPtrPtr)->create();
{ {
const std::list<common::dataStructures::AdminUser> adminUsers = m_catalogue->getAdminUsers(); const std::list<common::dataStructures::AdminUser> adminUsers = m_catalogue->getAdminUsers();
...@@ -10373,29 +10378,4 @@ TEST_P(cta_catalogue_CatalogueTest, ping) { ...@@ -10373,29 +10378,4 @@ TEST_P(cta_catalogue_CatalogueTest, ping) {
m_catalogue->ping(); m_catalogue->ping();
} }
TEST_P(cta_catalogue_CatalogueTest, schemaTables) {
const auto tableNameList = m_conn->getTableNames();
std::set<std::string> tableNameSet;
std::map<std::string, uint32_t> tableNameToListPos;
uint32_t listPos = 0;
for(auto &tableName: tableNameList) {
ASSERT_EQ(tableNameToListPos.end(), tableNameToListPos.find(tableName));
tableNameToListPos[tableName] = listPos++;
}
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("ADMIN_USER"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("ARCHIVE_FILE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("ARCHIVE_ROUTE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("CTA_CATALOGUE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("LOGICAL_LIBRARY"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("MOUNT_POLICY"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("REQUESTER_GROUP_MOUNT_RULE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("REQUESTER_MOUNT_RULE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("STORAGE_CLASS"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("TAPE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("TAPE_FILE"));
ASSERT_NE(tableNameToListPos.end(), tableNameToListPos.find("TAPE_POOL"));
}
} // namespace unitTests } // namespace unitTests
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#include "catalogue/CatalogueFactory.hpp" #include "catalogue/CatalogueFactory.hpp"
#include "common/exception/Exception.hpp" #include "common/exception/Exception.hpp"
#include "common/log/DummyLogger.hpp" #include "common/log/DummyLogger.hpp"
#include "rdbms/wrapper/Conn.hpp"
#include "rdbms/LoginFactory.hpp"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <map> #include <map>
...@@ -32,7 +30,7 @@ ...@@ -32,7 +30,7 @@
namespace unitTests { namespace unitTests {
class cta_catalogue_CatalogueTest : public ::testing::TestWithParam<cta::rdbms::LoginFactory*> { class cta_catalogue_CatalogueTest : public ::testing::TestWithParam<cta::catalogue::CatalogueFactory **> {
public: public:
cta_catalogue_CatalogueTest(); cta_catalogue_CatalogueTest();
...@@ -44,12 +42,6 @@ protected: ...@@ -44,12 +42,6 @@ protected:
cta::common::dataStructures::SecurityIdentity m_localAdmin; cta::common::dataStructures::SecurityIdentity m_localAdmin;
cta::common::dataStructures::SecurityIdentity m_admin; cta::common::dataStructures::SecurityIdentity m_admin;
/**
* A general purpose database connection outside of the m_catalogue object to
* be used to run tests directly on the underlying "raw" catalogue database.
*/
std::unique_ptr<cta::rdbms::wrapper::Conn> m_conn;
virtual void SetUp(); virtual void SetUp();
virtual void TearDown(); virtual void TearDown();
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "catalogue/CatalogueFactory.hpp" #include "catalogue/CatalogueFactoryFactory.hpp"
#include "catalogue/CreateAdminUserCmd.hpp" #include "catalogue/CreateAdminUserCmd.hpp"
#include "catalogue/CreateAdminUserCmdLineArgs.hpp" #include "catalogue/CreateAdminUserCmdLineArgs.hpp"
#include "common/exception/Exception.hpp" #include "common/exception/Exception.hpp"
...@@ -57,7 +57,8 @@ int CreateAdminUserCmd::exceptionThrowingMain(const int argc, char *const *const ...@@ -57,7 +57,8 @@ int CreateAdminUserCmd::exceptionThrowingMain(const int argc, char *const *const
const uint64_t nbDbConns = 1; const uint64_t nbDbConns = 1;
const uint64_t nbArchiveFileListingDbConns = 1; const uint64_t nbArchiveFileListingDbConns = 1;
log::DummyLogger dummyLog("dummy", "dummy"); log::DummyLogger dummyLog("dummy", "dummy");
auto catalogue = CatalogueFactory::create(dummyLog, dbLogin, nbDbConns, nbArchiveFileListingDbConns); auto catalogueFactory = CatalogueFactoryFactory::create(dummyLog, dbLogin, nbDbConns, nbArchiveFileListingDbConns);
auto catalogue = catalogueFactory->create();
const common::dataStructures::SecurityIdentity adminRunningCommand(getUsername(), getHostname()); const common::dataStructures::SecurityIdentity adminRunningCommand(getUsername(), getHostname());
catalogue->createAdminUser(adminRunningCommand, cmdLineArgs.adminUsername, cmdLineArgs.comment); catalogue->createAdminUser(adminRunningCommand, cmdLineArgs.adminUsername, cmdLineArgs.comment);
......
...@@ -17,41 +17,10 @@ ...@@ -17,41 +17,10 @@
*/ */
#include "catalogue/CatalogueTest.hpp" #include "catalogue/CatalogueTest.hpp"
#include "tests/CatalogueUnitTestsCmdLineArgs.hpp" #include "tests/GlobalCatalogueFactoryForUnitTests.hpp"
namespace {
/**
* Creates Login objects for the test catalogue database whose database login
* details are specified in a database configuration file passed on the
* command-line to the catalogue unit-tests program.
*/
class DbConfigFileLoginFactory: public cta::rdbms::LoginFactory {
public:
/**
* Destructor.
*/
virtual ~DbConfigFileLoginFactory() {
}
/**
* Returns a newly created Login object.
*
* @return A newly created Login object.
*/
virtual cta::rdbms::Login create() {
return cta::rdbms::Login::parseFile(g_cmdLineArgs.dbConfigPath);
}
}; // class OracleLoginFactory