Skip to content
Snippets Groups Projects
Commit 050372ac authored by Eric Cano's avatar Eric Cano
Browse files

Created a new class ConfigurationFile that turns a text file into a double map...

Created a new class ConfigurationFile that turns a text file into a double map of categories/keys entries.
The map also contains the line number from which the configuration is comming.
parent 23d6629a
Branches
Tags
No related merge requests found
......@@ -2,7 +2,15 @@ cmake_minimum_required (VERSION 2.6)
add_library(ctatapedaemon
CommandLineParams.cpp
ConfigurationFile.cpp
GlobalConfiguration.cpp
TapeDaemon.cpp
TpconfigLine.cpp
TpconfigLines.cpp)
\ No newline at end of file
TpconfigLines.cpp)
add_library(ctadaemonunittests SHARED
ConfigurationFileTests.cpp)
target_link_libraries(ctadaemonunittests
ctatapedaemon
unitTestHelper)
\ No newline at end of file
/*
* 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 "ConfigurationFile.hpp"
#include "common/exception/Exception.hpp"
#include <fstream>
#include <algorithm>
namespace cta { namespace tape { namespace daemon {
ConfigurationFile::ConfigurationFile(const std::string& path) {
// Try to open the configuration file, throwing an exception if there is a
// failure
std::ifstream file(path);
if (file.fail()) {
cta::exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": Failed to open configuration file"
": m_fileName=" << path;
throw ex;
}
std::string line;
size_t lineNumber=0;
while(++lineNumber, std::getline(file, line)) {
// get rid of potential tabs
std::replace(line.begin(),line.end(),'\t',' ');
// get the category
std::istringstream sline(line);
std::string category;
if (!(sline >> category)) continue; // empty line
if (category[0] == '#') continue; // comment
// get the key
std::string key;
if (!(sline >> key)) continue; // no key on line
if (key[0] == '#') continue; // key commented
// get and store value
while (sline.get() == ' '){}; sline.unget(); // skip spaces
std::string value;
std::getline(sline, value, '#');
value.erase(value.find_last_not_of(" \n\r\t")+1); // right trim
auto & entry = entries[category][key];
entry.value = value;
entry.line = lineNumber;
}
}
}}} // namespace cta::tape::daemon
\ No newline at end of file
/*
* 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 <map>
#include <string>
namespace cta { namespace tape { namespace daemon {
struct ConfigurationFile {
public:
ConfigurationFile(const std::string & path);
struct value_t {
std::string value;
uint32_t line;
};
std::map<std::string, std::map<std::string, value_t> > entries;
};
}}} // namespace cta::tape::daemon
\ No newline at end of file
/*
* 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 <gtest/gtest.h>
#include "ConfigurationFile.hpp"
#include "tests/TempFile.hpp"
namespace unitTests {
TEST(cta_Daemon, ConfigurationFile) {
TempFile tf;
tf.stringFill("# My test config file\n"
"cat1 key1 val1\n"
"cat1 #key2 val2\n"
"cat1 key3 #val3\n");
cta::tape::daemon::ConfigurationFile cf(tf.path());
ASSERT_EQ(1, cf.entries.size());
ASSERT_NO_THROW(cf.entries.at("cat1").at("key1"));
ASSERT_EQ("val1", cf.entries.at("cat1").at("key1").value);
ASSERT_EQ(2, cf.entries.at("cat1").at("key1").line);
}
} // namespace unitTests
\ No newline at end of file
......@@ -17,6 +17,7 @@
*/
#include "GlobalConfiguration.hpp"
#include "ConfigurationFile.hpp"
namespace cta { namespace tape { namespace daemon {
......@@ -27,9 +28,22 @@ GlobalConfiguration GlobalConfiguration::createFromCtaConf(cta::log::Logger& log
GlobalConfiguration GlobalConfiguration::createFromCtaConf(
const std::string& generalConfigPath, cta::log::Logger& log) {
GlobalConfiguration ret;
// Parse config file
ConfigurationFile cf(generalConfigPath);
// Extract configuration from parsed config file
// tpConfigPath: this element is optional
try {
ConfigurationFile::value_t & v = cf.entries.at("Taped").at("tpConfigPath");
std::stringstream src;
src << generalConfigPath << ":" << v.line;
ret.tpConfigPath.set(v.value, src.str());
} catch (...) {}
return ret;
}
GlobalConfiguration::GlobalConfiguration():
tpConfigPath("tpConfigPath", "/etc/cta/TPCONFIG", "Compile time default") {}
cta::log::DummyLogger GlobalConfiguration::gDummyLogger("");
}}} // namespace cta::tape::daemon
......@@ -19,8 +19,11 @@
#pragma once
#include <string>
#include <map>
#include <type_traits>
#include <limits>
#include "DriveConfiguration.hpp"
#include "common/log/DummyLogger.hpp"
#include "common/exception/Exception.hpp"
namespace cta {
namespace tape {
......@@ -35,7 +38,48 @@ struct GlobalConfiguration {
static GlobalConfiguration createFromCtaConf(
const std::string & generalConfigPath,
cta::log::Logger & log = gDummyLogger);
// Default constructor.
GlobalConfiguration();
std::map<std::string, DriveConfiguration> driveConfigs;
/**
* A templated class allowing the tracking of parameter with their source.
* If the parameter is not set (implicitly defined as the source being
* an empty string), access to the value will be denied (exception)
*/
template<class C>
class SourcedParameter {
public:
CTA_GENERATE_EXCEPTION_CLASS(ParameterNotDefined);
SourcedParameter(const std::string & name): m_name(name) {
if (std::is_arithmetic<C>::value) {
m_value=std::numeric_limits<C>::max();
}
}
SourcedParameter(const std::string & name, C value, const std::string & source):
m_name(name), m_value(value), m_source(source) {}
C operator() () {
if (m_source.empty()) {
throw ParameterNotDefined(std::string("In SourcedParameter::operator(): "
"value not defined for parameter \'" + m_name + "\' :"));
}
return m_value;
}
void set(const std::string & value, const std::string & source) {
m_value = value;
m_source = source;
}
const std::string & name() { return m_name; }
const std::string & source() { return m_source; }
private:
std::string m_name;
C m_value;
std::string m_source;
};
// The actual parameters:
SourcedParameter<std::string> tpConfigPath;
private:
/** A private dummy logger which will simplify the implementaion of the
* functions (just unconditionally log things). */
......
......@@ -43,10 +43,14 @@ target_link_libraries(cta-unitTests
ctaremotensunittests
ctaschedulerunittests
ctaio
ctadaemonunittests
${GMOCK_LIB}
gtest
pthread)
add_library(unitTestHelper
TempFile.cpp)
add_library(systemTestHelper
Subprocess.cpp)
......
/*
* 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 "TempFile.hpp"
#include "common/exception/Errnum.hpp"
#include <stdlib.h>
#include <unistd.h>
#include <fstream>
#include <memory>
namespace unitTests {
TempFile::TempFile() {
char path[] = "/tmp/testCTA-XXXXXX";
int fd = ::mkstemp(path);
cta::exception::Errnum::throwOnMinusOne(fd, "In TempFile::TempFile: failed to mkstemp: ");
::close(fd);
m_path = path;
}
TempFile::TempFile(const std::string& path) : m_path(path) { }
TempFile::~TempFile() {
if (m_path.size()) {
::unlink(m_path.c_str());
}
}
std::string TempFile::path() {
return m_path;
}
void TempFile::randomFill(size_t size) {
std::ofstream out(m_path, std::ios::out | std::ios::binary);
std::ifstream in("/dev/urandom", std::ios::in | std::ios::binary);
std::unique_ptr<char[] > buff(new char[size]);
in.read(buff.get(), size);
out.write(buff.get(), size);
}
void TempFile::stringFill(const std::string& string) {
std::ofstream out(m_path, std::ios::out | std::ios::binary | std::ios::trunc);
out << string;
}
void TempFile::stringAppend(const std::string& string) {
std::ofstream out(m_path, std::ios::out | std::ios::binary | std::ios::app);
out << string;
}
}
\ No newline at end of file
/*
* 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 <string>
namespace unitTests {
/**
* A class creating a temporary file (deleted by destructor). Various population
* operations are provided.
*/
class TempFile {
public:
TempFile();
TempFile(const std::string& path);
std::string path();
void randomFill(size_t size);
void stringFill(const std::string &string);
void stringAppend(const std::string &string);
~TempFile();
private:
std::string m_path;
};
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment