blob: c564671d2763c1958f7a8e48486f53dcb06f2788 [file] [log] [blame]
Weiqi Shi68f2cf62014-08-26 12:35:45 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento49f3a5f2017-09-23 01:36:33 -04002/*
Davide Pesaventod8521aa2023-09-17 14:21:27 -04003 * Copyright (c) 2014-2023, Regents of the University of California.
Weiqi Shi68f2cf62014-08-26 12:35:45 -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
Alexander Afanasyev42290b22017-03-09 12:58:29 -080017 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Weiqi Shi68f2cf62014-08-26 12:35:45 -070018 */
19
20/**
Davide Pesavento8891c832019-03-20 23:20:35 -040021 * @file This file demonstrates how to generate data to be stored in a repo using
22 * the repo watch protocol and repo insertion protocol.
23 *
24 * The details of the protocols can be found here:
Alexander Afanasyev42290b22017-03-09 12:58:29 -080025 * <https://redmine.named-data.net/projects/repo-ng/wiki/Watched_Prefix_Insertion_Protocol>
26 * <https://redmine.named-data.net/projects/repo-ng/wiki/Basic_Repo_Insertion_Protocol>
Weiqi Shi68f2cf62014-08-26 12:35:45 -070027 *
28 * This file is used for debugging purpose. There are two modes for users to assign
29 * names for the data.
30 * 1)read the data name from a specific file
31 * 2)input a prefix and a random version number will be added automatically
32 * Users need to run nfd and repo-ng and set up specific repo protocols mentioned
33 * above before running this program.
34 * The description of command parameter can be found in the function usage().
35 */
36
Davide Pesaventod8521aa2023-09-17 14:21:27 -040037#include <boost/asio/io_context.hpp>
Weiqi Shi68f2cf62014-08-26 12:35:45 -070038#include <boost/lexical_cast.hpp>
Davide Pesavento8891c832019-03-20 23:20:35 -040039
40#include <ndn-cxx/data.hpp>
41#include <ndn-cxx/face.hpp>
42#include <ndn-cxx/name.hpp>
43#include <ndn-cxx/util/random.hpp>
44#include <ndn-cxx/util/scheduler.hpp>
45#include <ndn-cxx/util/time.hpp>
46
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040047#include <fstream>
Weiqi Shi68f2cf62014-08-26 12:35:45 -070048#include <iostream>
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040049#include <random>
50#include <string>
Weiqi Shi68f2cf62014-08-26 12:35:45 -070051
Davide Pesaventod8521aa2023-09-17 14:21:27 -040052namespace repo::examples {
Weiqi Shi68f2cf62014-08-26 12:35:45 -070053
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040054enum Mode {
Weiqi Shi68f2cf62014-08-26 12:35:45 -070055 AUTO,
56 READFILE
57};
58
59class Publisher
60{
61public:
62 class Error : public std::runtime_error
63 {
64 public:
Davide Pesavento8891c832019-03-20 23:20:35 -040065 using std::runtime_error::runtime_error;
Weiqi Shi68f2cf62014-08-26 12:35:45 -070066 };
67
68public:
Weiqi Shi68f2cf62014-08-26 12:35:45 -070069 void
70 run();
71
72 void
73 autoGenerate();
74
75 void
76 generateFromFile();
77
Davide Pesavento8891c832019-03-20 23:20:35 -040078 static std::shared_ptr<ndn::Data>
Weiqi Shi68f2cf62014-08-26 12:35:45 -070079 createData(const ndn::Name& name);
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040080
Weiqi Shi68f2cf62014-08-26 12:35:45 -070081public:
82 std::ifstream insertStream;
Davide Pesaventod8521aa2023-09-17 14:21:27 -040083 Mode mode{AUTO};
84 ndn::Name dataPrefix{"/example/data"};
85 ndn::time::milliseconds timeInterval{2000};
86 ndn::time::milliseconds duration{0};
Weiqi Shi68f2cf62014-08-26 12:35:45 -070087
88private:
89 ndn::Face m_face;
Davide Pesavento164ae3b2023-11-11 22:00:23 -050090 ndn::Scheduler m_scheduler{m_face.getIoContext()};
Davide Pesaventod8521aa2023-09-17 14:21:27 -040091 std::uniform_int_distribution<> m_randomDist{200, 1000};
Weiqi Shi68f2cf62014-08-26 12:35:45 -070092};
93
94void
95Publisher::run()
96{
Weiqi Shi68f2cf62014-08-26 12:35:45 -070097 if (mode == AUTO) {
Davide Pesavento8891c832019-03-20 23:20:35 -040098 m_scheduler.schedule(timeInterval, [this] { autoGenerate(); });
Weiqi Shi68f2cf62014-08-26 12:35:45 -070099 }
100 else {
Davide Pesavento8891c832019-03-20 23:20:35 -0400101 m_scheduler.schedule(timeInterval, [this] { generateFromFile(); });
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700102 }
103 m_face.processEvents(duration);
104}
105
106void
107Publisher::autoGenerate()
108{
Davide Pesavento8891c832019-03-20 23:20:35 -0400109 ndn::Name name = dataPrefix;
110 name.appendNumber(m_randomDist(ndn::random::getRandomNumberEngine()));
111 auto data = createData(name);
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700112 m_face.put(*data);
Davide Pesavento8891c832019-03-20 23:20:35 -0400113
114 m_scheduler.schedule(timeInterval, [this] { autoGenerate(); });
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700115}
116
117void
118Publisher::generateFromFile()
119{
120 if (insertStream.eof()) {
Davide Pesavento164ae3b2023-11-11 22:00:23 -0500121 m_face.getIoContext().stop();
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700122 return;
Davide Pesavento8891c832019-03-20 23:20:35 -0400123 }
124
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700125 std::string name;
126 getline(insertStream, name);
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400127 auto data = createData(name);
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700128 m_face.put(*data);
Davide Pesavento8891c832019-03-20 23:20:35 -0400129
130 m_scheduler.schedule(timeInterval, [this] { generateFromFile(); });
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700131}
132
Davide Pesavento8891c832019-03-20 23:20:35 -0400133std::shared_ptr<ndn::Data>
134Publisher::createData(const ndn::Name& name)
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700135{
136 static ndn::KeyChain keyChain;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400137 static const std::vector<uint8_t> content(1500, '-');
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700138
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400139 auto data = std::make_shared<ndn::Data>(name);
140 data->setContent(content);
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700141 keyChain.sign(*data);
142 return data;
143}
144
145static void
146usage()
147{
148 std::cerr
149 << " Publisher [-d dataPrefix] [-f filename] [-s duration time] [-t generate time interval] \n"
150 << " -d: specify the data prefix publisher generate\n"
151 << " -f: specify filename that publish would read from\n"
152 << " -s: specify the time duration of generate data\n"
153 << " -t: specify the time interval between two data generated\n"
154 << std::endl;
155 exit(1);
156}
157
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400158static int
Davide Pesavento8891c832019-03-20 23:20:35 -0400159main(int argc, char* argv[])
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700160{
161 Publisher generator;
162 bool isAuto = false;
163 bool isRead = false;
164 int opt;
165 while ((opt = getopt(argc, argv, "d:f:s:t:")) != -1) {
166 switch (opt) {
167 case 'd':
168 {
Davide Pesavento8891c832019-03-20 23:20:35 -0400169 generator.dataPrefix = ndn::Name(std::string(optarg));
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700170 generator.mode = AUTO;
171 isAuto = true;
172 }
173 break;
174 case 'f':
175 {
176 isRead = true;
177 generator.mode = READFILE;
178 std::string str = std::string(optarg);
179 generator.insertStream.open(str.c_str());
180 if (!generator.insertStream.is_open()) {
181 std::cerr << "ERROR: cannot open " << std::string(optarg) << std::endl;
182 return 1;
183 }
184 }
185 break;
186 case 's':
187 try {
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400188 generator.duration = ndn::time::milliseconds(boost::lexical_cast<uint64_t>(optarg));
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700189 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800190 catch (const boost::bad_lexical_cast&) {
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400191 std::cerr << "-s option should be an integer" << std::endl;
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700192 return 1;
193 }
194 break;
195 case 't':
196 try {
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400197 generator.timeInterval = ndn::time::milliseconds(boost::lexical_cast<uint64_t>(optarg));
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700198 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800199 catch (const boost::bad_lexical_cast&) {
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400200 std::cerr << "-t option should be an integer" << std::endl;
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700201 return 1;
202 }
203 break;
204 default:
205 usage();
206 break;
207 }
208 }
209
210 argc -= optind;
211 argv += optind;
212
213 if (argc != 0)
214 usage();
215
216 if (isAuto && isRead)
217 usage();
218
219 generator.run();
220 return 0;
221}
222
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400223} // namespace repo::examples
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700224
225int
Davide Pesavento8891c832019-03-20 23:20:35 -0400226main(int argc, char* argv[])
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700227{
228 try {
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400229 return repo::examples::main(argc, argv);
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700230 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800231 catch (const std::exception& e) {
Weiqi Shi68f2cf62014-08-26 12:35:45 -0700232 std::cerr << "ERROR: " << e.what() << std::endl;
233 return 2;
234 }
235}