ServiceConfig.cpp 7.61 KB
Newer Older
1
2
#include <cmath>
#include <iomanip>
3
4
5
6
7
8
9
10
11
#include "ServiceConfig.hpp"
#include "hepnos/Exception.hpp"
#include <yaml-cpp/yaml.h>

namespace hepnos {

struct ServiceConfig::Impl {

    std::string m_address;
12
    uint32_t    m_numRanks;
13
14
15
16
    bool        m_hasDatabase;
    std::string m_databasePath;
    std::string m_databaseName;
    std::string m_databaseType;
17
18
    uint32_t    m_databaseProviders = 1;
    uint32_t    m_databaseTargets = 1;
19
20
21
    bool        m_hasStorage;
    std::string m_storagePath;
    size_t      m_storageSize;
22
23
24
    uint32_t    m_storageProviders = 1;
    uint32_t    m_storageTargets = 1;
    uint32_t    m_numThreads = 1;
25
26
27
};

static YAML::Node loadAndValidate(const std::string& filename);
28
29
30
static std::string formatString(const std::string& str, 
        int rank, int provider, int target,
        int maxRank, int maxProvider, int maxTarget);
31

32
ServiceConfig::ServiceConfig(const std::string& filename, int rank, int numRanks)
33
34
: m_impl(std::make_unique<Impl>()) {
    
35
36
    m_impl->m_numRanks = numRanks;

37
38
    YAML::Node config       = loadAndValidate(filename);
    YAML::Node address      = config["address"];
39
    YAML::Node threads      = config["threads"];
40
41
    YAML::Node db_node      = config["database"];
    YAML::Node storage_node = config["storage"];
42
43
44
45
46
    if(threads) {
        m_impl->m_numThreads = threads.as<uint32_t>();
    }
    if(m_impl->m_numThreads == 0) m_impl->m_numThreads = 1;
    
47
48
49
50
51
    m_impl->m_address = address.as<std::string>();
    if(!db_node) {
        m_impl->m_hasDatabase  = false;
    } else {
        m_impl->m_hasDatabase  = true;
52
        m_impl->m_databasePath = db_node["path"].as<std::string>();
53
54
        m_impl->m_databaseName = db_node["name"].as<std::string>();
        m_impl->m_databaseType = db_node["type"].as<std::string>();
55
56
57
58
59
60
        if(db_node["providers"]) {
            m_impl->m_databaseProviders = db_node["providers"].as<uint32_t>();
        }
        if(db_node["targets"]) {
            m_impl->m_databaseTargets = db_node["targets"].as<uint32_t>();
        }
61
62
63
64
65
    }
    if(!storage_node) {
        m_impl->m_hasStorage   = false;
    } else {
        m_impl->m_hasStorage   = true;
66
        m_impl->m_storagePath  = storage_node["path"].as<std::string>();
67
        m_impl->m_storageSize  = storage_node["size"].as<size_t>();
68
69
70
71
72
73
        if(storage_node["providers"]) {
            m_impl->m_storageProviders = storage_node["providers"].as<uint32_t>();
        }
        if(storage_node["targets"]) {
            m_impl->m_storageTargets = storage_node["targets"].as<uint32_t>();
        }
74
75
76
77
78
79
80
81
82
83
84
85
86
    }
}

ServiceConfig::~ServiceConfig() {}

const std::string& ServiceConfig::getAddress() const {
    return m_impl->m_address;
}

bool ServiceConfig::hasDatabase() const {
    return m_impl->m_hasDatabase;
}

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
std::string ServiceConfig::getDatabasePath(int rank, int provider, int target) const {
    int maxRank     = m_impl->m_numRanks - 1;
    int maxProvider = getNumDatabaseProviders() - 1;
    int maxTarget   = getNumDatabaseTargets() - 1;
    return formatString(m_impl->m_databasePath, rank, provider, target, maxRank, maxProvider, maxTarget);
}

std::string ServiceConfig::getDatabaseName(int rank, int provider, int target) const {
    int maxRank     = m_impl->m_numRanks - 1;
    int maxProvider = getNumDatabaseProviders() - 1;
    int maxTarget   = getNumDatabaseTargets() - 1;
    return formatString(m_impl->m_databaseName, rank, provider, target, maxRank, maxProvider, maxTarget);
}

const std::string& ServiceConfig::getDatabasePathTemplate() const {
102
103
104
    return m_impl->m_databasePath;
}

105
const std::string& ServiceConfig::getDatabaseNameTemplate() const {
106
107
108
109
110
111
112
    return m_impl->m_databaseName;
}

const std::string& ServiceConfig::getDatabaseType() const {
    return m_impl->m_databaseType;
}

113
114
115
116
117
118
119
120
uint32_t ServiceConfig::getNumDatabaseProviders() const {
    return m_impl->m_databaseProviders;
}

uint32_t ServiceConfig::getNumDatabaseTargets() const {
    return m_impl->m_databaseTargets;
}

121
122
123
124
bool ServiceConfig::hasStorage() const {
    return m_impl->m_hasStorage;
}

125
126
127
128
129
130
131
132
std::string ServiceConfig::getStoragePath(int rank, int provider, int target) const {
    int maxRank     = m_impl->m_numRanks - 1;
    int maxProvider = getNumStorageProviders() - 1;
    int maxTarget   = getNumStorageTargets() - 1;
    return formatString(m_impl->m_storagePath, rank, provider, target, maxRank, maxProvider, maxTarget);
}

const std::string& ServiceConfig::getStoragePathTemplate() const {
133
134
135
136
137
138
139
    return m_impl->m_storagePath;
}

size_t ServiceConfig::getStorageSize() const {
    return m_impl->m_storageSize;
}

140
141
142
143
144
145
146
147
148
149
150
151
uint32_t ServiceConfig::getNumStorageProviders() const {
    return m_impl->m_storageProviders;
}

uint32_t ServiceConfig::getNumStorageTargets() const {
    return m_impl->m_storageTargets;
}

uint32_t ServiceConfig::getNumThreads() const {
    return m_impl->m_numThreads;
}

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
static YAML::Node loadAndValidate(const std::string& filename) {
    YAML::Node config = YAML::LoadFile(filename);
    if(!config["address"]) {
        throw Exception("\"address\" field not found in configuration file.");
    }
    if(!config["database"]) {
        throw Exception("\"database\" field not found in configuration file.");
    }
    if(!config["database"]["path"]) {
        throw Exception("\"database.path\" field not found in configuration file.");
    }
    if(!config["database"]["name"]) {
        throw Exception("\"database.name\" field not found in configuration file.");
    }
    if(!config["database"]["type"]) {
        throw Exception("\"database.type\" field not found in configuration file.");
    }
    std::string db_type = config["database"]["type"].as<std::string>();
Matthieu Dorier's avatar
Matthieu Dorier committed
170
171
    if(db_type != "null"
    && db_type != "map"
172
173
    && db_type != "ldb"
    && db_type != "bdb") {
Matthieu Dorier's avatar
Matthieu Dorier committed
174
        throw Exception("\"database.type\" field should be \"null\", \"map\", \"ldb\", or \"bdb\".");
175
176
177
178
179
180
181
182
183
184
185
186
    }
    if(config["storage"]) {
        if(!config["storage"]["path"]) {
            throw Exception("\"storage.path\" field not found in configuration file.");
        }
        if(!config["storage"]["size"]) {
            throw Exception("\"storage.size\" field not found in configuration file.");
        }
    }
    return config;
}

187
188
189
static std::string formatString(const std::string& str, 
        int rank, int provider, int target,
        int maxRank=0, int maxProvider=0, int maxTarget=0) {
190
191
    std::string result = str;
    std::stringstream ssrank;
192
193
194
195
196
    ssrank << std::setw(log10(maxRank+1)+1) << std::setfill('0') << rank;
    std::stringstream ssprovider;
    ssprovider << std::setw(log10(maxProvider+1)+1) << std::setfill('0') << provider;
    std::stringstream sstarget;
    sstarget << std::setw(log10(maxTarget+1)+1) << std::setfill('0') << target;
197
    std::string srank = ssrank.str();
198
199
200
    std::string sprovider = ssprovider.str();
    std::string starget = sstarget.str();
    size_t index = 0;
201
202
203
204
205
206
207
208
209
210
    while (true) {
        index = result.find("$RANK", index);
        if (index == std::string::npos) break;
        if(rank >= 0) {
            result.replace(index, 5, srank.c_str());
        } else {
            result.replace(index, 5, "");
        }
        index += 5;
    }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
    index = 0;
    while (true) {
        index = result.find("$PROVIDER", index);
        if (index == std::string::npos) break;
        if(rank >= 0) {
            result.replace(index, 9, sprovider.c_str());
        } else {
            result.replace(index, 9, "");
        }
        index += 9;
    }
    index = 0;
    while (true) {
        index = result.find("$TARGET", index);
        if (index == std::string::npos) break;
        if(rank >= 0) {
            result.replace(index, 7, starget.c_str());
        } else {
            result.replace(index, 7, "");
        }
        index += 7;
    }
233
234
235
236
237
    return result;
}

}