blob: d9bfa1f2c4badb8b13773bb73c64630687b299b0 [file] [log] [blame]
Junxiao Shi7357ef22016-09-07 02:39:37 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Junxiao Shi7357ef22016-09-07 02:39:37 +00004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_MGMT_NFD_CONTROLLER_HPP
23#define NDN_MGMT_NFD_CONTROLLER_HPP
24
25#include "control-command.hpp"
26#include "control-response.hpp"
27#include "status-dataset.hpp"
28#include "command-options.hpp"
29#include "../../security/validator-null.hpp"
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -080030#include "../../security/key-chain.hpp"
Alexander Afanasyev80782e02017-01-04 13:16:54 -080031#include "../../security/command-interest-signer.hpp"
Junxiao Shi7357ef22016-09-07 02:39:37 +000032
33namespace ndn {
34
35namespace security {
Junxiao Shi7357ef22016-09-07 02:39:37 +000036class Validator;
37} // namespace security
38class Face;
39
40namespace nfd {
41
42/**
43 * \defgroup management Management
44 * \brief Classes and data structures to manage NDN forwarder
45 */
46
47/**
48 * \ingroup management
49 * \brief NFD Management protocol client
50 * \sa https://redmine.named-data.net/projects/nfd/wiki/Management
51 */
52class Controller : noncopyable
53{
54public:
55 /** \brief a callback on command success
56 */
57 typedef function<void(const ControlParameters&)> CommandSucceedCallback;
58
59 /** \brief a callback on command failure
60 */
61 typedef function<void(const ControlResponse&)> CommandFailCallback;
62
63 /** \brief a callback on dataset retrieval failure
64 */
65 typedef function<void(uint32_t code, const std::string& reason)> DatasetFailCallback;
66
67 /** \brief construct a Controller that uses face for transport,
68 * and uses the passed KeyChain to sign commands
69 */
Alexander Afanasyev80782e02017-01-04 13:16:54 -080070 Controller(Face& face, KeyChain& keyChain, security::Validator& validator = s_validatorNull);
Junxiao Shi7357ef22016-09-07 02:39:37 +000071
72 /** \brief start command execution
73 */
74 template<typename Command>
75 void
76 start(const ControlParameters& parameters,
77 const CommandSucceedCallback& onSuccess,
78 const CommandFailCallback& onFailure,
79 const CommandOptions& options = CommandOptions())
80 {
81 shared_ptr<ControlCommand> command = make_shared<Command>();
82 this->startCommand(command, parameters, onSuccess, onFailure, options);
83 }
84
85 /** \brief start dataset fetching
86 */
87 template<typename Dataset>
88 typename std::enable_if<std::is_default_constructible<Dataset>::value>::type
89 fetch(const std::function<void(typename Dataset::ResultType)>& onSuccess,
90 const DatasetFailCallback& onFailure,
91 const CommandOptions& options = CommandOptions())
92 {
93 this->fetchDataset(make_shared<Dataset>(), onSuccess, onFailure, options);
94 }
95
96 /** \brief start dataset fetching
97 */
98 template<typename Dataset, typename ParamType = typename Dataset::ParamType>
99 void
100 fetch(const ParamType& param,
101 const std::function<void(typename Dataset::ResultType)>& onSuccess,
102 const DatasetFailCallback& onFailure,
103 const CommandOptions& options = CommandOptions())
104 {
105 this->fetchDataset(make_shared<Dataset>(param), onSuccess, onFailure, options);
106 }
107
108private:
109 void
110 startCommand(const shared_ptr<ControlCommand>& command,
111 const ControlParameters& parameters,
112 const CommandSucceedCallback& onSuccess,
113 const CommandFailCallback& onFailure,
114 const CommandOptions& options);
115
116 void
117 processCommandResponse(const Data& data,
118 const shared_ptr<ControlCommand>& command,
119 const CommandSucceedCallback& onSuccess,
120 const CommandFailCallback& onFailure);
121
122 void
123 processValidatedCommandResponse(const Data& data,
124 const shared_ptr<ControlCommand>& command,
125 const CommandSucceedCallback& onSuccess,
126 const CommandFailCallback& onFailure);
127
128 template<typename Dataset>
129 void
130 fetchDataset(shared_ptr<Dataset> dataset,
131 const std::function<void(typename Dataset::ResultType)>& onSuccess,
132 const DatasetFailCallback& onFailure,
133 const CommandOptions& options);
134
135 void
136 fetchDataset(const Name& prefix,
137 const std::function<void(const ConstBufferPtr&)>& processResponse,
138 const DatasetFailCallback& onFailure,
139 const CommandOptions& options);
140
141 template<typename Dataset>
142 void
143 processDatasetResponse(shared_ptr<Dataset> dataset,
144 const std::function<void(typename Dataset::ResultType)>& onSuccess,
145 const DatasetFailCallback& onFailure,
146 ConstBufferPtr payload);
147
148 void
149 processDatasetFetchError(const DatasetFailCallback& onFailure, uint32_t code, std::string msg);
150
151public:
152 /** \brief error code for timeout
153 */
154 static const uint32_t ERROR_TIMEOUT;
155
156 /** \brief error code for network Nack
157 */
158 static const uint32_t ERROR_NACK;
159
160 /** \brief error code for response validation failure
161 */
162 static const uint32_t ERROR_VALIDATION;
163
164 /** \brief error code for server error
165 */
166 static const uint32_t ERROR_SERVER;
167
168 /** \brief inclusive lower bound of error codes
169 */
170 static const uint32_t ERROR_LBOUND;
171
172protected:
173 Face& m_face;
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800174 KeyChain& m_keyChain;
175 security::CommandInterestSigner m_signer;
Junxiao Shi7357ef22016-09-07 02:39:37 +0000176 security::Validator& m_validator;
177
178private:
179 static ValidatorNull s_validatorNull;
180};
181
182template<typename Dataset>
183inline void
184Controller::fetchDataset(shared_ptr<Dataset> dataset,
185 const std::function<void(typename Dataset::ResultType)>& onSuccess1,
186 const DatasetFailCallback& onFailure1,
187 const CommandOptions& options)
188{
189 const std::function<void(typename Dataset::ResultType)>& onSuccess = onSuccess1 ?
190 onSuccess1 : [] (const typename Dataset::ResultType&) {};
191 const DatasetFailCallback& onFailure = onFailure1 ?
192 onFailure1 : [] (uint32_t, const std::string&) {};
193
194 Name prefix = dataset->getDatasetPrefix(options.getPrefix());
195 this->fetchDataset(prefix,
196 bind(&Controller::processDatasetResponse<Dataset>, this, dataset, onSuccess, onFailure, _1),
197 onFailure,
198 options);
199}
200
201template<typename Dataset>
202inline void
203Controller::processDatasetResponse(shared_ptr<Dataset> dataset,
204 const std::function<void(typename Dataset::ResultType)>& onSuccess,
205 const DatasetFailCallback& onFailure,
206 ConstBufferPtr payload)
207{
208 typename Dataset::ResultType result;
209 try {
210 result = dataset->parseResult(payload);
211 }
212 catch (const tlv::Error& e) {
213 onFailure(ERROR_SERVER, e.what());
214 return;
215 }
216
217 onSuccess(result);
218}
219
220} // namespace nfd
221} // namespace ndn
222
223#endif // NDN_MGMT_NFD_CONTROLLER_HPP