blob: c0f028f651f1c1be77d7a0747807662443cf09b1 [file] [log] [blame]
Chengyu Fan46398212015-08-11 11:23:13 -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#include <ndn-cxx/face.hpp>
20#include <ndn-cxx/security/key-chain.hpp>
21#include <json/value.h>
22#include <json/writer.h>
23#include <json/reader.h>
24#include <iostream>
25#include <fstream>
26#include <getopt.h>
27
28void
29usage(const char *fileName)
30{
31 std::cout << "\n Usage:\n " << fileName <<
32 "[-h] [-f name list file] \n"
33 " [-c catalogPrefix] - set the catalog prefix\n"
34 " [-f name list file] - set the file that contains name list\n"
35 " [-n namespace] - set the publisher namespace\n"
36 " [-h] - print help and exit\n"
37 "\n";
38}
39
40namespace ndn {
41namespace atmos {
42
43class Producer : noncopyable
44{
45public:
46 void
47 run()
48 {
49 if (m_jsonFile.empty()) {
50 std::cout << "jsonFile is empty! exiting ..." << std::endl;
51 return;
52 }
53 m_face.setInterestFilter(m_namespace,
54 bind(&Producer::onInterest, this, _1, _2),
55 bind(&Producer::onRegisterSucceed, this, _1),
56 bind(&Producer::onRegisterFailed, this, _1, _2));
57 m_face.processEvents();
58 }
59
60private:
61 void
62 onInterest(const InterestFilter& filter, const Interest& interest)
63 {
64 std::cout << "<< I: " << interest << std::endl;
65
66 // Create new name, based on Interest's name
67 Name dataName(interest.getName());
68
69 Json::Value publishValue; // will contains the root value after parsing.
70 Json::Reader reader;
71 std::ifstream test(m_jsonFile, std::ifstream::binary);
72 bool parsingSuccessful = reader.parse(test, publishValue, false);
73 if (!parsingSuccessful) {
74 // report to the user the failure and their locations in the document.
75 std::cout << reader.getFormattedErrorMessages() << std::endl;
76 }
77
78 Json::FastWriter fastWriter;
79 const std::string jsonMessage = fastWriter.write(publishValue);
80 const char* payload = jsonMessage.c_str();
81 size_t payLoadLength = jsonMessage.size() + 1;
82
83 // Create Data packet
84 shared_ptr<Data> data = make_shared<Data>();
85 data->setName(dataName);
86 data->setFreshnessPeriod(time::seconds(10));
87 // todo: set the correct segment number
88 // assume that the last component it the segment number
89 data->setFinalBlockId(interest.getName()[-1]);
90 data->setContent(reinterpret_cast<const uint8_t*>(payload), payLoadLength);
91
92 // Sign Data packet with default identity
93 m_keyChain.sign(*data);
94
95 // Return Data packet to the requester
96 std::cout << ">> D: " << *data << std::endl;
97 m_face.put(*data);
98 m_face.shutdown();
99 }
100
101
102 void
103 onRegisterFailed(const Name& prefix, const std::string& reason)
104 {
105 std::cerr << "ERROR: Failed to register prefix \""
106 << prefix << "\" in local hub's daemon (" << reason << ")"
107 << std::endl;
108 m_face.shutdown();
109 }
110
111 void
112 onRegisterSucceed(const Name& prefix)
113 {
114 std::cout << "register succeed" << std::endl;
115 Interest interest(Name(m_catalogPrefix).append("publish").append(m_namespace));
116 interest.setInterestLifetime(time::milliseconds(1000));
117 interest.setMustBeFresh(true);
118
119 m_face.expressInterest(interest,
120 bind(&Producer::onData, this, _1, _2),
121 bind(&Producer::onTimeout, this, _1));
122
123 std::cout << "Sending " << interest << std::endl;
124 }
125
126 void
127 onData(const Interest& interest, const Data& data)
128 {
129 std::cout << data << std::endl;
130 }
131
132 void
133 onTimeout(const Interest& interest)
134 {
135 std::cout << "Timeout " << interest << std::endl;
136 }
137
138public:
139 std::string m_jsonFile;
140 std::string m_namespace;
141 std::string m_catalogPrefix;
142
143private:
144 Face m_face;
145 KeyChain m_keyChain;
146};
147
148}
149}
150
151int
152main(int argc, char** argv)
153{
154 ndn::atmos::Producer producer;
155 int option;
156 if (argc < 7) {
157 usage(argv[0]);
158 return 0;
159 }
160
161 while ((option = getopt(argc, argv, "c:f:n:h")) != -1) {
162 switch (option) {
163 case 'c':
164 producer.m_catalogPrefix.assign(optarg);
165 break;
166 case 'f':
167 producer.m_jsonFile.assign(optarg);
168 break;
169 case 'n':
170 producer.m_namespace.assign(optarg);
171 break;
172 case 'h':
173 default:
174 usage(argv[0]);
175 return 0;
176 }
177 }
178
179 argc -= optind;
180 argv += optind;
181 if (argc != 0) {
182 usage(argv[0]);
183 return 1;
184 }
185
186 try {
187 producer.run();
188 }
189 catch (const std::exception& e) {
190 std::cerr << "ERROR: " << e.what() << std::endl;
191 }
192 return 0;
193}