blob: 9d29434a782c5cdf6d64285f70d59ccb98f2a7d8 [file] [log] [blame]
Alison Craig2a4d5282015-04-10 12:00:02 -06001/** NDN-Atmos: Cataloging Service for distributed data originally developed
2 * for atmospheric science data
3 * Copyright (C) 2015 Colorado State University
4 *
5 * NDN-Atmos is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * NDN-Atmos is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with NDN-Atmos. If not, see <http://www.gnu.org/licenses/>.
17**/
18
19#ifndef ATMOS_PUBLISH_PUBLISH_ADAPTER_HPP
20#define ATMOS_PUBLISH_PUBLISH_ADAPTER_HPP
21
22#include "util/catalog-adapter.hpp"
23#include "util/mysql-util.hpp"
24
25#include <json/reader.h>
26#include <json/value.h>
27#include <json/writer.h>
28
29#include <ndn-cxx/face.hpp>
30#include <ndn-cxx/interest.hpp>
31#include <ndn-cxx/interest-filter.hpp>
32#include <ndn-cxx/name.hpp>
33#include <ndn-cxx/security/key-chain.hpp>
Chengyu Fanb25835b2015-04-28 17:09:35 -060034#include <ndn-cxx/security/validator.hpp>
Alison Craig2a4d5282015-04-10 12:00:02 -060035#include "mysql/mysql.h"
36
37#include <memory>
38#include <string>
Chengyu Fanb25835b2015-04-28 17:09:35 -060039#include <vector>
40#include <unordered_map>
Alison Craig2a4d5282015-04-10 12:00:02 -060041
42namespace atmos {
43namespace publish {
Alison Craig2a4d5282015-04-10 12:00:02 -060044/**
45 * PublishAdapter handles the Publish usecases for the catalog
46 */
47template <typename DatabaseHandler>
Chengyu Fanb25835b2015-04-28 17:09:35 -060048class PublishAdapter : public atmos::util::CatalogAdapter {
Alison Craig2a4d5282015-04-10 12:00:02 -060049public:
50 /**
51 * Constructor
52 *
Chengyu Fanb25835b2015-04-28 17:09:35 -060053 * @param face: Face that will be used for NDN communications
54 * @param keyChain: KeyChain that will be used for data signing
Alison Craig2a4d5282015-04-10 12:00:02 -060055 */
Chengyu Fanb25835b2015-04-28 17:09:35 -060056 PublishAdapter(const std::shared_ptr<ndn::Face>& face,
57 const std::shared_ptr<ndn::KeyChain>& keyChain);
Alison Craig2a4d5282015-04-10 12:00:02 -060058
Alison Craig2a4d5282015-04-10 12:00:02 -060059 virtual
60 ~PublishAdapter();
61
Chengyu Fanb25835b2015-04-28 17:09:35 -060062 /**
63 * Helper function that subscribe to a publish section for the config file
64 */
65 void
66 setConfigFile(util::ConfigFile& config,
67 const ndn::Name& prefix);
68
Alison Craig2a4d5282015-04-10 12:00:02 -060069protected:
70 /**
Chengyu Fanb25835b2015-04-28 17:09:35 -060071 * Helper function that configures piblishAdapter instance according to publish section
72 * in config file
73 */
74 void
75 onConfig(const util::ConfigSection& section,
76 bool isDryDun,
77 const std::string& fileName,
78 const ndn::Name& prefix);
79
80 /**
Alison Craig2a4d5282015-04-10 12:00:02 -060081 * Initial "please publish this" Interests
82 *
83 * @param filter: InterestFilter that caused this Interest to be routed
84 * @param interest: Interest that needs to be handled
85 */
86 virtual void
Chengyu Fanb25835b2015-04-28 17:09:35 -060087 onPublishInterest(const ndn::InterestFilter& filter, const ndn::Interest& interest);
Alison Craig2a4d5282015-04-10 12:00:02 -060088
89 /**
90 * Data containing the actual thing we need to publish
91 *
92 * @param interest: Interest that caused this Data to be routed
93 * @param data: Data that needs to be handled
94 */
95 virtual void
Chengyu Fanb25835b2015-04-28 17:09:35 -060096 onPublishedData(const ndn::Interest& interest, const ndn::Data& data);
Alison Craig2a4d5282015-04-10 12:00:02 -060097
Chengyu Fanb25835b2015-04-28 17:09:35 -060098 /**
99 * Helper function to set the DatabaseHandler
100 */
101 void
102 setDatabaseHandler(const util::ConnectionDetails& databaseId);
Alison Craig2a4d5282015-04-10 12:00:02 -0600103
Chengyu Fanb25835b2015-04-28 17:09:35 -0600104 /**
105 * Helper function that sets filters to make the adapter work
106 */
107 void
108 setFilters();
109
110protected:
111 typedef std::unordered_map<ndn::Name, const ndn::RegisteredPrefixId*> RegisteredPrefixList;
112 // Prefix for ChronoSync
113 ndn::Name m_syncPrefix;
114 // Handle to the Catalog's database
115 std::shared_ptr<DatabaseHandler> m_databaseHandler;
116 std::shared_ptr<ndn::Validator> m_validaor;
117 RegisteredPrefixList m_registeredPrefixList;
Alison Craig2a4d5282015-04-10 12:00:02 -0600118};
119
Alison Craig2a4d5282015-04-10 12:00:02 -0600120
Chengyu Fanb25835b2015-04-28 17:09:35 -0600121template <typename DatabaseHandler>
122PublishAdapter<DatabaseHandler>::PublishAdapter(const std::shared_ptr<ndn::Face>& face,
123 const std::shared_ptr<ndn::KeyChain>& keyChain)
124 : util::CatalogAdapter(face, keyChain)
125{
126}
127
128template <typename DatabaseHandler>
129void
130PublishAdapter<DatabaseHandler>::setFilters()
131{
132 ndn::Name publishPrefix = ndn::Name(m_prefix).append("publish");
133 m_registeredPrefixList[publishPrefix] = m_face->setInterestFilter(publishPrefix,
134 bind(&publish::PublishAdapter<DatabaseHandler>::onPublishInterest,
135 this, _1, _2),
136 bind(&publish::PublishAdapter<DatabaseHandler>::onRegisterSuccess,
137 this, _1),
138 bind(&publish::PublishAdapter<DatabaseHandler>::onRegisterFailure,
139 this, _1, _2));
Alison Craig2a4d5282015-04-10 12:00:02 -0600140}
141
142template <typename DatabaseHandler>
143PublishAdapter<DatabaseHandler>::~PublishAdapter()
144{
Chengyu Fanb25835b2015-04-28 17:09:35 -0600145 for (const auto& itr : m_registeredPrefixList) {
146 if (static_cast<bool>(itr.second))
147 m_face->unsetInterestFilter(itr.second);
148 }
Alison Craig2a4d5282015-04-10 12:00:02 -0600149}
150
151template <typename DatabaseHandler>
152void
Chengyu Fanb25835b2015-04-28 17:09:35 -0600153PublishAdapter<DatabaseHandler>::setConfigFile(util::ConfigFile& config,
154 const ndn::Name& prefix)
155{
156 config.addSectionHandler("publishAdapter",
157 bind(&PublishAdapter<DatabaseHandler>::onConfig, this,
158 _1, _2, _3, prefix));
159}
160
161template <typename DatabaseHandler>
162void
163PublishAdapter<DatabaseHandler>::onConfig(const util::ConfigSection& section,
164 bool isDryRun,
165 const std::string& filename,
166 const ndn::Name& prefix)
167{
168 using namespace util;
169 if (isDryRun) {
170 return;
171 }
172
173 std::string signingId, dbServer, dbName, dbUser, dbPasswd;
174 std::string syncPrefix("ndn:/ndn-atmos/broadcast/chronosync");
175
176 for (auto item = section.begin();
177 item != section.end();
178 ++ item)
179 {
180 if (item->first == "signingId") {
181 signingId.assign(item->second.get_value<std::string>());
182 if (signingId.empty()) {
183 throw Error("Invalid value for \"signingId\""
184 " in \"publish\" section");
185 }
186 }
187
188 // @todo: parse the published_file_security section
189
190 else if (item->first == "database") {
191 const util::ConfigSection& databaseSection = item->second;
192 for (auto subItem = databaseSection.begin();
193 subItem != databaseSection.end();
194 ++ subItem) {
195 if (subItem->first == "dbServer") {
196 dbServer.assign(subItem->second.get_value<std::string>());
197 if (dbServer.empty()){
198 throw Error("Invalid value for \"dbServer\""
199 " in \"publish\" section");
200 }
201 }
202 if (subItem->first == "dbName") {
203 dbName.assign(subItem->second.get_value<std::string>());
204 if (dbName.empty()){
205 throw Error("Invalid value for \"dbName\""
206 " in \"publish\" section");
207 }
208 }
209 if (subItem->first == "dbUser") {
210 dbUser.assign(subItem->second.get_value<std::string>());
211 if (dbUser.empty()){
212 throw Error("Invalid value for \"dbUser\""
213 " in \"publish\" section");
214 }
215 }
216 if (subItem->first == "dbPasswd") {
217 dbPasswd.assign(subItem->second.get_value<std::string>());
218 if (dbPasswd.empty()){
219 throw Error("Invalid value for \"dbPasswd\""
220 " in \"publish\" section");
221 }
222 }
223 }
224 }
225 else if (item->first == "sync") {
226 const util::ConfigSection& synSection = item->second;
227 for (auto subItem = synSection.begin();
228 subItem != synSection.end();
229 ++ subItem) {
230 if (subItem->first == "prefix") {
231 syncPrefix.clear();
232 syncPrefix.assign(subItem->second.get_value<std::string>());
233 if (syncPrefix.empty()){
234 throw Error("Invalid value for \"prefix\""
235 " in \"publish\\sync\" section");
236 }
237 }
238 // todo: parse the sync_security section
239 }
240 }
241 }
242
243 m_prefix = prefix;
244 m_signingId = ndn::Name(signingId);
245 m_syncPrefix.clear();
246 m_syncPrefix.append(syncPrefix);
247 util::ConnectionDetails mysqlId(dbServer, dbUser, dbPasswd, dbName);
248
249 setDatabaseHandler(mysqlId);
250 setFilters();
251}
252
253template <typename DatabaseHandler>
254void
255PublishAdapter<DatabaseHandler>::setDatabaseHandler(const util::ConnectionDetails& databaseId)
256{
257 //empty
258}
259
260template <>
261void
262PublishAdapter<MYSQL>::setDatabaseHandler(const util::ConnectionDetails& databaseId)
263{
264 std::shared_ptr<MYSQL> conn = atmos::util::MySQLConnectionSetup(databaseId);
265
266 m_databaseHandler = conn;
267}
268
269template <typename DatabaseHandler>
270void
271PublishAdapter<DatabaseHandler>::onPublishInterest(const ndn::InterestFilter& filter,
272 const ndn::Interest& interest)
Alison Craig2a4d5282015-04-10 12:00:02 -0600273{
274 // @todo: Request the data for publish
275}
276
277template <typename DatabaseHandler>
278void
Chengyu Fanb25835b2015-04-28 17:09:35 -0600279PublishAdapter<DatabaseHandler>::onPublishedData(const ndn::Interest& interest,
280 const ndn::Data& data)
Alison Craig2a4d5282015-04-10 12:00:02 -0600281{
282 // @todo handle publishing the data
283}
284
285} // namespace publish
286} // namespace atmos
287#endif //ATMOS_PUBLISH_PUBLISH_ADAPTER_HPP