blob: bb52b45f008daaa5a14fa181a96ba87b107de0d7 [file] [log] [blame]
Shuo Chen478204c2014-03-18 18:27:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevc0e26582017-08-13 21:16:49 -04002/*
Alexander Afanasyev42290b22017-03-09 12:58:29 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -07004 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Shuo Chen478204c2014-03-18 18:27:04 -070018 */
19
20#include "repo.hpp"
Weiqi Shif0330d52014-07-09 10:54:27 -070021#include "storage/sqlite-storage.hpp"
Wentao Shanga8f3c402014-10-30 14:03:27 -070022
Shuo Chen478204c2014-03-18 18:27:04 -070023namespace repo {
24
25RepoConfig
26parseConfig(const std::string& configPath)
27{
28 if (configPath.empty()) {
29 std::cerr << "configuration file path is empty" << std::endl;
30 }
31
32 std::ifstream fin(configPath.c_str());
Nick Gordon190e4dc2017-10-04 16:54:10 -050033 if (!fin.is_open())
Alexander Afanasyev42290b22017-03-09 12:58:29 -080034 BOOST_THROW_EXCEPTION(Repo::Error("failed to open configuration file '"+ configPath +"'"));
Shuo Chen478204c2014-03-18 18:27:04 -070035
36 using namespace boost::property_tree;
37 ptree propertyTree;
38 try {
39 read_info(fin, propertyTree);
40 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -080041 catch (const ptree_error& e) {
42 BOOST_THROW_EXCEPTION(Repo::Error("failed to read configuration file '"+ configPath +"'"));
Shuo Chen478204c2014-03-18 18:27:04 -070043 }
44
45 ptree repoConf = propertyTree.get_child("repo");
46
47 RepoConfig repoConfig;
Shuo Chen028dcd32014-06-21 16:36:44 +080048 repoConfig.repoConfigPath = configPath;
Shuo Chen478204c2014-03-18 18:27:04 -070049
50 ptree dataConf = repoConf.get_child("data");
Alexander Afanasyev81203b92017-11-09 13:53:56 -050051 for (const auto& section : dataConf) {
Nick Gordon190e4dc2017-10-04 16:54:10 -050052 if (section.first == "prefix")
53 repoConfig.dataPrefixes.push_back(Name(section.second.get_value<std::string>()));
54 else if (section.first == "registration-subset")
55 repoConfig.registrationSubset = section.second.get_value<int>();
Shuo Chen478204c2014-03-18 18:27:04 -070056 else
Nick Gordon190e4dc2017-10-04 16:54:10 -050057 BOOST_THROW_EXCEPTION(Repo::Error("Unrecognized '" + section.first + "' option in 'data' section in "
Alexander Afanasyev42290b22017-03-09 12:58:29 -080058 "configuration file '"+ configPath +"'"));
Shuo Chen478204c2014-03-18 18:27:04 -070059 }
60
61 ptree commandConf = repoConf.get_child("command");
Alexander Afanasyev81203b92017-11-09 13:53:56 -050062 for (const auto& section : commandConf) {
Nick Gordon190e4dc2017-10-04 16:54:10 -050063 if (section.first == "prefix")
64 repoConfig.repoPrefixes.push_back(Name(section.second.get_value<std::string>()));
Shuo Chen478204c2014-03-18 18:27:04 -070065 else
Nick Gordon190e4dc2017-10-04 16:54:10 -050066 BOOST_THROW_EXCEPTION(Repo::Error("Unrecognized '" + section.first + "' option in 'command' section in "
Alexander Afanasyev42290b22017-03-09 12:58:29 -080067 "configuration file '"+ configPath +"'"));
Shuo Chen478204c2014-03-18 18:27:04 -070068 }
69
Alexander Afanasyev81203b92017-11-09 13:53:56 -050070 auto tcpBulkInsert = repoConf.get_child_optional("tcp_bulk_insert");
Shuo Chen478204c2014-03-18 18:27:04 -070071 bool isTcpBulkEnabled = false;
72 std::string host = "localhost";
73 std::string port = "7376";
Alexander Afanasyev81203b92017-11-09 13:53:56 -050074 if (tcpBulkInsert) {
75 for (const auto& section : *tcpBulkInsert) {
76 isTcpBulkEnabled = true;
Shuo Chen478204c2014-03-18 18:27:04 -070077
Alexander Afanasyev81203b92017-11-09 13:53:56 -050078 // tcp_bulk_insert {
79 // host "localhost" ; IP address or hostname to listen on
80 // port 7635 ; Port number to listen on
81 // }
82 if (section.first == "host") {
83 host = section.second.get_value<std::string>();
84 }
85 else if (section.first == "port") {
86 port = section.second.get_value<std::string>();
87 }
88 else
89 BOOST_THROW_EXCEPTION(Repo::Error("Unrecognized '" + section.first + "' option in 'tcp_bulk_insert' section in "
90 "configuration file '"+ configPath +"'"));
Shuo Chen478204c2014-03-18 18:27:04 -070091 }
Shuo Chen478204c2014-03-18 18:27:04 -070092 }
93 if (isTcpBulkEnabled) {
94 repoConfig.tcpBulkInsertEndpoints.push_back(std::make_pair(host, port));
95 }
96
Alexander Afanasyev42290b22017-03-09 12:58:29 -080097 if (repoConf.get<std::string>("storage.method") != "sqlite") {
98 BOOST_THROW_EXCEPTION(Repo::Error("Only 'sqlite' storage method is supported"));
99 }
Shuo Chen478204c2014-03-18 18:27:04 -0700100
101 repoConfig.dbPath = repoConf.get<std::string>("storage.path");
102
103 repoConfig.validatorNode = repoConf.get_child("validator");
Weiqi Shif0330d52014-07-09 10:54:27 -0700104
Shuo Chen6e818122015-05-04 10:40:03 +0800105 repoConfig.nMaxPackets = repoConf.get<uint64_t>("storage.max-packets");
Weiqi Shif0330d52014-07-09 10:54:27 -0700106
Shuo Chen478204c2014-03-18 18:27:04 -0700107 return repoConfig;
108}
109
Shuo Chen478204c2014-03-18 18:27:04 -0700110Repo::Repo(boost::asio::io_service& ioService, const RepoConfig& config)
111 : m_config(config)
112 , m_scheduler(ioService)
Wentao Shang91fb4f22014-05-20 10:55:22 -0700113 , m_face(ioService)
Wentao Shanga8f3c402014-10-30 14:03:27 -0700114 , m_store(std::make_shared<SqliteStorage>(config.dbPath))
Weiqi Shif0330d52014-07-09 10:54:27 -0700115 , m_storageHandle(config.nMaxPackets, *m_store)
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400116 , m_validator(m_face)
Nick Gordon190e4dc2017-10-04 16:54:10 -0500117 , m_readHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_config.registrationSubset)
Weiqi Shif0330d52014-07-09 10:54:27 -0700118 , m_writeHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
Weiqi Shi098f91c2014-07-23 17:41:35 -0700119 , m_watchHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
Weiqi Shif0330d52014-07-09 10:54:27 -0700120 , m_deleteHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
121 , m_tcpBulkInsertHandle(ioService, m_storageHandle)
Shuo Chen478204c2014-03-18 18:27:04 -0700122
123{
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000124 this->enableValidation();
Shuo Chen478204c2014-03-18 18:27:04 -0700125}
126
127void
Shuo Chena12f5282014-08-01 15:18:30 +0800128Repo::initializeStorage()
129{
130 // Rebuild storage if storage checkpoin exists
131 ndn::time::steady_clock::TimePoint start = ndn::time::steady_clock::now();
132 m_storageHandle.initialize();
133 ndn::time::steady_clock::TimePoint end = ndn::time::steady_clock::now();
134 ndn::time::milliseconds cost = ndn::time::duration_cast<ndn::time::milliseconds>(end - start);
135 std::cerr << "initialize storage cost: " << cost << "ms" << std::endl;
136}
137
138void
Shuo Chen478204c2014-03-18 18:27:04 -0700139Repo::enableListening()
140{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000141 for (const ndn::Name& dataPrefix : m_config.dataPrefixes) {
142 // ReadHandle performs prefix registration internally.
143 m_readHandle.listen(dataPrefix);
144 }
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000145 for (const ndn::Name& cmdPrefix : m_config.repoPrefixes) {
146 m_face.registerPrefix(cmdPrefix, nullptr,
147 [] (const Name& cmdPrefix, const std::string& reason) {
148 std::cerr << "Command prefix " << cmdPrefix << " registration error: " << reason << std::endl;
149 BOOST_THROW_EXCEPTION(Error("Command prefix registration failed"));
150 });
Shuo Chen478204c2014-03-18 18:27:04 -0700151
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000152 m_writeHandle.listen(cmdPrefix);
153 m_watchHandle.listen(cmdPrefix);
154 m_deleteHandle.listen(cmdPrefix);
155 }
156
157 for (const auto& ep : m_config.tcpBulkInsertEndpoints) {
158 m_tcpBulkInsertHandle.listen(ep.first, ep.second);
159 }
Shuo Chen478204c2014-03-18 18:27:04 -0700160}
161
Shuo Chen028dcd32014-06-21 16:36:44 +0800162void
163Repo::enableValidation()
164{
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400165 m_validator.load(m_config.validatorNode, m_config.repoConfigPath);
Shuo Chen028dcd32014-06-21 16:36:44 +0800166}
167
Shuo Chen478204c2014-03-18 18:27:04 -0700168} // namespace repo