blob: 2c6f3b0df37675568503a630d588ad32c79ebfc5 [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;
47
48 ptree dataConf = repoConf.get_child("data");
49
50 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))
115 , m_readHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler)
116 , m_writeHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
117 , m_deleteHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
118 , m_tcpBulkInsertHandle(ioService, *m_storageHandle)
119
120{
121 //Trust model not implemented, this is just an empty validator
122 //@todo add a function to parse RepoConfig.validatorNode and define the trust model
123 m_validator.addInterestRule("^<>",
124 *m_keyChain.
125 getCertificate(m_keyChain.getDefaultCertificateName()));
126}
127
128shared_ptr<StorageHandle>
129Repo::openStorage(const RepoConfig& config)
130{
131 shared_ptr<StorageHandle> storageHandle = ndn::make_shared<SqliteHandle>(config.dbPath);
132 return storageHandle;
133}
134
135void
136Repo::enableListening()
137{
138 // Enable "listening" on Data prefixes
139 for (vector<ndn::Name>::iterator it = m_config.dataPrefixes.begin();
140 it != m_config.dataPrefixes.end();
141 ++it)
142 {
143 m_readHandle.listen(*it);
144 }
145
146 // Enable "listening" on control prefixes
147 for (vector<ndn::Name>::iterator it = m_config.repoPrefixes.begin();
148 it != m_config.repoPrefixes.end();
149 ++it)
150 {
151 m_writeHandle.listen(*it);
152 m_deleteHandle.listen(*it);
153 }
154
155 // Enable listening on TCP bulk insert addresses
156 for (vector<pair<string, string> >::iterator it = m_config.tcpBulkInsertEndpoints.begin();
157 it != m_config.tcpBulkInsertEndpoints.end();
158 ++it)
159 {
160 m_tcpBulkInsertHandle.listen(it->first, it->second);
161 }
162}
163
164} // namespace repo