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
ArchiveFileItorImpl.cpp
Catalogue.cpp
CatalogueFactory.cpp
CatalogueFactoryFactory.cpp
ChecksumTypeMismatch.cpp
ChecksumValueMismatch.cpp
CmdLineTool.cpp
FileSizeMismatch.cpp
InMemoryCatalogue.cpp
InMemoryCatalogueFactory.cpp
MysqlCatalogue.cpp
MysqlCatalogueFactory.cpp
MysqlCatalogueSchema.cpp
OracleCatalogue.cpp
OracleCatalogueFactory.cpp
PostgresqlCatalogueFactory.cpp
SqliteCatalogueSchema.cpp
TapeFileWritten.cpp
TapeItemImplementation.cpp
......@@ -40,8 +47,7 @@ set (CATALOGUE_LIB_SRC_FILES
RdbmsCatalogue.cpp
SchemaCreatingSqliteCatalogue.cpp
SqliteCatalogue.cpp
MysqlCatalogue.cpp
MysqlCatalogueSchema.cpp
SqliteCatalogueFactory.cpp
TapeForWriting.cpp
UserSpecifiedANonEmptyTape.cpp
UserSpecifiedANonExistentTape.cpp
......@@ -123,7 +129,6 @@ add_custom_command(OUTPUT MysqlCatalogueSchema.cpp
set(IN_MEMORY_CATALOGUE_UNIT_TESTS_LIB_SRC_FILES
CatalogueTest.cpp
CatalogueFactoryTest.cpp
InMemoryCatalogueTest.cpp
InMemoryVersionOfCatalogueTest.cpp)
......
......@@ -17,61 +17,14 @@
*/
#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 catalogue {
//------------------------------------------------------------------------------
// create
// destructor
//------------------------------------------------------------------------------
std::unique_ptr<Catalogue> CatalogueFactory::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:
{
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());
}
CatalogueFactory:: ~CatalogueFactory() {
}
} // namespace catalogue
......
......@@ -19,48 +19,27 @@
#pragma once
#include "catalogue/Catalogue.hpp"
#include "rdbms/Login.hpp"
#include <memory>
#include <mutex>
namespace cta {
namespace catalogue {
/**
* Factory for creating CTA catalogue objects. This class is a singleton.
* Specifies the interface to a factory Catalogue objects.
*/
class CatalogueFactory {
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.
*
* @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.
* Returns a newly created CTA catalogue object.
*/
static std::unique_ptr<Catalogue> create(
log::Logger &log,
const rdbms::Login &login,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect = 3);
virtual std::unique_ptr<Catalogue> create() = 0;
}; // 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 @@
*/
#include "catalogue/ArchiveFileRow.hpp"
#include "catalogue/CatalogueFactory.hpp"
#include "catalogue/CatalogueTest.hpp"
#include "catalogue/ChecksumTypeMismatch.hpp"
#include "catalogue/ChecksumValueMismatch.hpp"
......@@ -40,6 +39,8 @@
#include "common/exception/UserError.hpp"
#include "common/make_unique.hpp"
#include "rdbms/wrapper/ConnFactoryFactory.hpp"
#include "rdbms/Conn.hpp"
#include "rdbms/ConnPool.hpp"
#include <algorithm>
#include <gtest/gtest.h>
......@@ -71,13 +72,17 @@ void cta_catalogue_CatalogueTest::SetUp() {
using namespace cta::catalogue;
try {
const rdbms::Login &login = GetParam()->create();
auto connFactory = rdbms::wrapper::ConnFactoryFactory::create(login);
const uint64_t nbConns = 2;
const uint64_t nbArchiveFileListingConns = 2;
CatalogueFactory *const *const catalogueFactoryPtrPtr = GetParam();
m_catalogue = CatalogueFactory::create(m_dummyLog, login, nbConns, nbArchiveFileListingConns);
m_conn = connFactory->create();
if(nullptr == catalogueFactoryPtrPtr) {
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();
......@@ -10373,29 +10378,4 @@ TEST_P(cta_catalogue_CatalogueTest, 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
......@@ -22,8 +22,6 @@
#include "catalogue/CatalogueFactory.hpp"
#include "common/exception/Exception.hpp"
#include "common/log/DummyLogger.hpp"
#include "rdbms/wrapper/Conn.hpp"
#include "rdbms/LoginFactory.hpp"
#include <gtest/gtest.h>
#include <map>
......@@ -32,7 +30,7 @@
namespace unitTests {
class cta_catalogue_CatalogueTest : public ::testing::TestWithParam<cta::rdbms::LoginFactory*> {
class cta_catalogue_CatalogueTest : public ::testing::TestWithParam<cta::catalogue::CatalogueFactory **> {
public:
cta_catalogue_CatalogueTest();
......@@ -44,12 +42,6 @@ protected:
cta::common::dataStructures::SecurityIdentity m_localAdmin;
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 TearDown();
......
......@@ -16,7 +16,7 @@
* 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/CreateAdminUserCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
......@@ -57,7 +57,8 @@ int CreateAdminUserCmd::exceptionThrowingMain(const int argc, char *const *const
const uint64_t nbDbConns = 1;
const uint64_t nbArchiveFileListingDbConns = 1;
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());
catalogue->createAdminUser(adminRunningCommand, cmdLineArgs.adminUsername, cmdLineArgs.comment);
......
......@@ -17,41 +17,10 @@
*/
#include "catalogue/CatalogueTest.hpp"
#include "tests/CatalogueUnitTestsCmdLineArgs.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
DbConfigFileLoginFactory g_dbConfigLoginFactory;
} // anonymous namespace
#include "tests/GlobalCatalogueFactoryForUnitTests.hpp"
namespace unitTests {
INSTANTIATE_TEST_CASE_P(DbConfigFile, cta_catalogue_CatalogueTest,
::testing::Values(dynamic_cast<cta::rdbms::LoginFactory*>(&g_dbConfigLoginFactory)));
INSTANTIATE_TEST_CASE_P(DbConfigFile, cta_catalogue_CatalogueTest, ::testing::Values(&g_catalogueFactoryForUnitTests));
} // namespace unitTests
/*
* 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/CatalogueRetryWrapper.hpp"
#include "catalogue/InMemoryCatalogueFactory.hpp"
#include "catalogue/InMemoryCatalogue.hpp"
#include "common/exception/Exception.hpp"
#include "common/make_unique.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
InMemoryCatalogueFactory::InMemoryCatalogueFactory(
log::Logger &log,
const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns,
const uint32_t maxTriesToConnect):
m_log(log),
m_nbConns(nbConns),
m_nbArchiveFileListingConns(nbArchiveFileListingConns),
m_maxTriesToConnect(maxTriesToConnect) {
}
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
std::unique_ptr<Catalogue> InMemoryCatalogueFactory::create() {
try {
auto c = cta::make_unique<InMemoryCatalogue>(m_log, m_nbConns, m_nbArchiveFileListingConns);
return cta::make_unique<CatalogueRetryWrapper>(m_log, std::move(c), m_maxTriesToConnect);
} 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