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