blob: d86850883283386acf8be8d64778265549c10ae6 [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"
21
22namespace 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");
107 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)
Shuo Chen478204c2014-03-18 18:27:04 -0700114 , m_storageHandle(openStorage(config))
Shuo Chen028dcd32014-06-21 16:36:44 +0800115 , m_validator(m_face)
Shuo Chen478204c2014-03-18 18:27:04 -0700116 , m_readHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler)
117 , m_writeHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
118 , m_deleteHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
119 , m_tcpBulkInsertHandle(ioService, *m_storageHandle)
120
121{
Shuo Chen478204c2014-03-18 18:27:04 -0700122}
123
124shared_ptr<StorageHandle>
125Repo::openStorage(const RepoConfig& config)
126{
127 shared_ptr<StorageHandle> storageHandle = ndn::make_shared<SqliteHandle>(config.dbPath);
128 return storageHandle;
129}
130
131void
132Repo::enableListening()
133{
134 // Enable "listening" on Data prefixes
135 for (vector<ndn::Name>::iterator it = m_config.dataPrefixes.begin();
136 it != m_config.dataPrefixes.end();
137 ++it)
138 {
139 m_readHandle.listen(*it);
140 }
141
142 // Enable "listening" on control prefixes
143 for (vector<ndn::Name>::iterator it = m_config.repoPrefixes.begin();
144 it != m_config.repoPrefixes.end();
145 ++it)
146 {
147 m_writeHandle.listen(*it);
148 m_deleteHandle.listen(*it);
149 }
150
151 // Enable listening on TCP bulk insert addresses
152 for (vector<pair<string, string> >::iterator it = m_config.tcpBulkInsertEndpoints.begin();
153 it != m_config.tcpBulkInsertEndpoints.end();
154 ++it)
155 {
156 m_tcpBulkInsertHandle.listen(it->first, it->second);
157 }
158}
159
Shuo Chen028dcd32014-06-21 16:36:44 +0800160void
161Repo::enableValidation()
162{
163 m_validator.load(m_config.validatorNode, m_config.repoConfigPath);
164}
165
Shuo Chen478204c2014-03-18 18:27:04 -0700166} // namespace repo