blob: 02c80da31a1043cbe90974641688a9c65f410dce [file] [log] [blame]
Shuo Chen478204c2014-03-18 18:27:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -07003 * Copyright (c) 2014, Regents of the University of California.
4 *
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"
Shuo Chen478204c2014-03-18 18:27:04 -070022namespace repo {
23
24RepoConfig
25parseConfig(const std::string& configPath)
26{
27 if (configPath.empty()) {
28 std::cerr << "configuration file path is empty" << std::endl;
29 }
30
31 std::ifstream fin(configPath.c_str());
32 if (!fin.is_open())
33 throw Repo::Error("failed to open configuration file '"+ configPath +"'");
34
35 using namespace boost::property_tree;
36 ptree propertyTree;
37 try {
38 read_info(fin, propertyTree);
39 }
40 catch (ptree_error& e) {
41 throw Repo::Error("failed to read configuration file '"+ configPath +"'");
42 }
43
44 ptree repoConf = propertyTree.get_child("repo");
45
46 RepoConfig repoConfig;
Shuo Chen028dcd32014-06-21 16:36:44 +080047 repoConfig.repoConfigPath = configPath;
Shuo Chen478204c2014-03-18 18:27:04 -070048
49 ptree dataConf = repoConf.get_child("data");
Shuo Chen478204c2014-03-18 18:27:04 -070050 for (ptree::const_iterator it = dataConf.begin();
51 it != dataConf.end();
52 ++it)
53 {
54 if (it->first == "prefix")
55 repoConfig.dataPrefixes.push_back(Name(it->second.get_value<std::string>()));
56 else
57 throw Repo::Error("Unrecognized '" + it->first + "' option in 'data' section in "
58 "configuration file '"+ configPath +"'");
59 }
60
61 ptree commandConf = repoConf.get_child("command");
62 for (ptree::const_iterator it = commandConf.begin();
63 it != commandConf.end();
64 ++it)
65 {
66 if (it->first == "prefix")
67 repoConfig.repoPrefixes.push_back(Name(it->second.get_value<std::string>()));
68 else
69 throw Repo::Error("Unrecognized '" + it->first + "' option in 'command' section in "
70 "configuration file '"+ configPath +"'");
71 }
72
73 ptree tcpBulkInsert = repoConf.get_child("tcp_bulk_insert");
74 bool isTcpBulkEnabled = false;
75 std::string host = "localhost";
76 std::string port = "7376";
77 for (ptree::const_iterator it = tcpBulkInsert.begin();
78 it != tcpBulkInsert.end();
79 ++it)
80 {
81 isTcpBulkEnabled = true;
82
83 // tcp_bulk_insert {
84 // host "localhost" ; IP address or hostname to listen on
85 // port 7635 ; Port number to listen on
86 // }
87 if (it->first == "host") {
88 host = it->second.get_value<std::string>();
89 }
90 else if (it->first == "port") {
91 port = it->second.get_value<std::string>();
92 }
93 else
94 throw Repo::Error("Unrecognized '" + it->first + "' option in 'tcp_bulk_insert' section in "
95 "configuration file '"+ configPath +"'");
96 }
97 if (isTcpBulkEnabled) {
98 repoConfig.tcpBulkInsertEndpoints.push_back(std::make_pair(host, port));
99 }
100
101 if (repoConf.get<std::string>("storage.method") != "sqlite")
102 throw Repo::Error("Only 'sqlite' storage method is supported");
103
104 repoConfig.dbPath = repoConf.get<std::string>("storage.path");
105
106 repoConfig.validatorNode = repoConf.get_child("validator");
Weiqi Shif0330d52014-07-09 10:54:27 -0700107
108 repoConfig.nMaxPackets = repoConf.get<int>("storage.max-packets");
109
Shuo Chen478204c2014-03-18 18:27:04 -0700110 return repoConfig;
111}
112
Shuo Chen478204c2014-03-18 18:27:04 -0700113Repo::Repo(boost::asio::io_service& ioService, const RepoConfig& config)
114 : m_config(config)
115 , m_scheduler(ioService)
Wentao Shang91fb4f22014-05-20 10:55:22 -0700116 , m_face(ioService)
Weiqi Shif0330d52014-07-09 10:54:27 -0700117 , m_store(make_shared<SqliteStorage>(config.dbPath))
118 , m_storageHandle(config.nMaxPackets, *m_store)
Shuo Chen028dcd32014-06-21 16:36:44 +0800119 , m_validator(m_face)
Weiqi Shif0330d52014-07-09 10:54:27 -0700120 , m_readHandle(m_face, m_storageHandle, m_keyChain, m_scheduler)
121 , m_writeHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
Weiqi Shi098f91c2014-07-23 17:41:35 -0700122 , m_watchHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
Weiqi Shif0330d52014-07-09 10:54:27 -0700123 , m_deleteHandle(m_face, m_storageHandle, m_keyChain, m_scheduler, m_validator)
124 , m_tcpBulkInsertHandle(ioService, m_storageHandle)
Shuo Chen478204c2014-03-18 18:27:04 -0700125
126{
Weiqi Shif0330d52014-07-09 10:54:27 -0700127 m_validator.load(config.validatorNode, config.repoConfigPath);
Shuo Chen478204c2014-03-18 18:27:04 -0700128}
129
130void
Shuo Chena12f5282014-08-01 15:18:30 +0800131Repo::initializeStorage()
132{
133 // Rebuild storage if storage checkpoin exists
134 ndn::time::steady_clock::TimePoint start = ndn::time::steady_clock::now();
135 m_storageHandle.initialize();
136 ndn::time::steady_clock::TimePoint end = ndn::time::steady_clock::now();
137 ndn::time::milliseconds cost = ndn::time::duration_cast<ndn::time::milliseconds>(end - start);
138 std::cerr << "initialize storage cost: " << cost << "ms" << std::endl;
139}
140
141void
Shuo Chen478204c2014-03-18 18:27:04 -0700142Repo::enableListening()
143{
144 // Enable "listening" on Data prefixes
145 for (vector<ndn::Name>::iterator it = m_config.dataPrefixes.begin();
146 it != m_config.dataPrefixes.end();
147 ++it)
148 {
149 m_readHandle.listen(*it);
150 }
151
152 // Enable "listening" on control prefixes
153 for (vector<ndn::Name>::iterator it = m_config.repoPrefixes.begin();
154 it != m_config.repoPrefixes.end();
155 ++it)
156 {
157 m_writeHandle.listen(*it);
Weiqi Shi098f91c2014-07-23 17:41:35 -0700158 m_watchHandle.listen(*it);
Shuo Chen478204c2014-03-18 18:27:04 -0700159 m_deleteHandle.listen(*it);
160 }
161
162 // Enable listening on TCP bulk insert addresses
163 for (vector<pair<string, string> >::iterator it = m_config.tcpBulkInsertEndpoints.begin();
164 it != m_config.tcpBulkInsertEndpoints.end();
165 ++it)
166 {
167 m_tcpBulkInsertHandle.listen(it->first, it->second);
168 }
169}
170
Shuo Chen028dcd32014-06-21 16:36:44 +0800171void
172Repo::enableValidation()
173{
174 m_validator.load(m_config.validatorNode, m_config.repoConfigPath);
175}
176
Shuo Chen478204c2014-03-18 18:27:04 -0700177} // namespace repo