blob: 422e7b7fdf4707fa6f4336105e39021c05ddc17a [file] [log] [blame]
Junxiao Shi7357ef22016-09-07 02:39:37 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -08002/*
Davide Pesaventodb4da5e2018-06-15 11:37:52 -04003 * Copyright (c) 2013-2018 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"
Alexander Afanasyev80782e02017-01-04 13:16:54 -080029#include "../../security/command-interest-signer.hpp"
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -080030#include "../../security/validator-null.hpp"
31#include "../../security/v2/key-chain.hpp"
32#include "../../security/v2/validator.hpp"
Ashlesh Gawande3e3a9892018-11-16 20:26:15 -060033#include "../../util/segment-fetcher.hpp"
Junxiao Shi7357ef22016-09-07 02:39:37 +000034
35namespace ndn {
36
Junxiao Shi7357ef22016-09-07 02:39:37 +000037class Face;
38
39namespace nfd {
40
41/**
42 * \defgroup management Management
43 * \brief Classes and data structures to manage NDN forwarder
44 */
45
46/**
47 * \ingroup management
48 * \brief NFD Management protocol client
49 * \sa https://redmine.named-data.net/projects/nfd/wiki/Management
50 */
51class Controller : noncopyable
52{
53public:
54 /** \brief a callback on command success
55 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040056 using CommandSucceedCallback = function<void(const ControlParameters&)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000057
58 /** \brief a callback on command failure
59 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040060 using CommandFailCallback = function<void(const ControlResponse&)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000061
62 /** \brief a callback on dataset retrieval failure
63 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040064 using DatasetFailCallback = function<void(uint32_t code, const std::string& reason)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000065
66 /** \brief construct a Controller that uses face for transport,
67 * and uses the passed KeyChain to sign commands
68 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040069 Controller(Face& face, KeyChain& keyChain,
70 security::v2::Validator& validator = security::getAcceptAllValidator());
Junxiao Shi7357ef22016-09-07 02:39:37 +000071
Ashlesh Gawande3e3a9892018-11-16 20:26:15 -060072 ~Controller();
73
Junxiao Shi7357ef22016-09-07 02:39:37 +000074 /** \brief start command execution
75 */
76 template<typename Command>
77 void
78 start(const ControlParameters& parameters,
79 const CommandSucceedCallback& onSuccess,
80 const CommandFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -070081 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +000082 {
Davide Pesavento3b101d02018-07-21 22:44:09 -040083 startCommand(make_shared<Command>(), parameters, onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +000084 }
85
86 /** \brief start dataset fetching
87 */
88 template<typename Dataset>
Davide Pesaventodb4da5e2018-06-15 11:37:52 -040089 std::enable_if_t<std::is_default_constructible<Dataset>::value>
Junxiao Shi7357ef22016-09-07 02:39:37 +000090 fetch(const std::function<void(typename Dataset::ResultType)>& onSuccess,
91 const DatasetFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -070092 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +000093 {
Davide Pesavento3b101d02018-07-21 22:44:09 -040094 fetchDataset(make_shared<Dataset>(), onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +000095 }
96
97 /** \brief start dataset fetching
98 */
99 template<typename Dataset, typename ParamType = typename Dataset::ParamType>
100 void
101 fetch(const ParamType& param,
102 const std::function<void(typename Dataset::ResultType)>& onSuccess,
103 const DatasetFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -0700104 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +0000105 {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400106 fetchDataset(make_shared<Dataset>(param), onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000107 }
108
109private:
110 void
111 startCommand(const shared_ptr<ControlCommand>& command,
112 const ControlParameters& parameters,
113 const CommandSucceedCallback& onSuccess,
114 const CommandFailCallback& onFailure,
115 const CommandOptions& options);
116
117 void
118 processCommandResponse(const Data& data,
119 const shared_ptr<ControlCommand>& command,
120 const CommandSucceedCallback& onSuccess,
121 const CommandFailCallback& onFailure);
122
123 void
124 processValidatedCommandResponse(const Data& data,
125 const shared_ptr<ControlCommand>& command,
126 const CommandSucceedCallback& onSuccess,
127 const CommandFailCallback& onFailure);
128
129 template<typename Dataset>
130 void
131 fetchDataset(shared_ptr<Dataset> dataset,
132 const std::function<void(typename Dataset::ResultType)>& onSuccess,
133 const DatasetFailCallback& onFailure,
134 const CommandOptions& options);
135
136 void
137 fetchDataset(const Name& prefix,
Eric Newberrye345baa2018-05-23 18:17:07 -0700138 const std::function<void(ConstBufferPtr)>& processResponse,
Junxiao Shi7357ef22016-09-07 02:39:37 +0000139 const DatasetFailCallback& onFailure,
140 const CommandOptions& options);
141
142 template<typename Dataset>
143 void
144 processDatasetResponse(shared_ptr<Dataset> dataset,
145 const std::function<void(typename Dataset::ResultType)>& onSuccess,
146 const DatasetFailCallback& onFailure,
147 ConstBufferPtr payload);
148
149 void
150 processDatasetFetchError(const DatasetFailCallback& onFailure, uint32_t code, std::string msg);
151
152public:
153 /** \brief error code for timeout
154 */
155 static const uint32_t ERROR_TIMEOUT;
156
157 /** \brief error code for network Nack
158 */
159 static const uint32_t ERROR_NACK;
160
161 /** \brief error code for response validation failure
162 */
163 static const uint32_t ERROR_VALIDATION;
164
165 /** \brief error code for server error
166 */
167 static const uint32_t ERROR_SERVER;
168
169 /** \brief inclusive lower bound of error codes
170 */
171 static const uint32_t ERROR_LBOUND;
172
173protected:
174 Face& m_face;
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800175 KeyChain& m_keyChain;
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -0800176 security::v2::Validator& m_validator;
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800177 security::CommandInterestSigner m_signer;
Ashlesh Gawande3e3a9892018-11-16 20:26:15 -0600178
179NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
180 std::set<shared_ptr<util::SegmentFetcher>> m_fetchers;
Junxiao Shi7357ef22016-09-07 02:39:37 +0000181};
182
183template<typename Dataset>
Davide Pesavento3b101d02018-07-21 22:44:09 -0400184void
Junxiao Shi7357ef22016-09-07 02:39:37 +0000185Controller::fetchDataset(shared_ptr<Dataset> dataset,
Davide Pesavento3b101d02018-07-21 22:44:09 -0400186 const std::function<void(typename Dataset::ResultType)>& onSuccess,
187 const DatasetFailCallback& onFailure,
Junxiao Shi7357ef22016-09-07 02:39:37 +0000188 const CommandOptions& options)
189{
Junxiao Shi7357ef22016-09-07 02:39:37 +0000190 Name prefix = dataset->getDatasetPrefix(options.getPrefix());
Davide Pesavento3b101d02018-07-21 22:44:09 -0400191 fetchDataset(prefix,
192 [=, d = std::move(dataset)] (ConstBufferPtr p) {
193 processDatasetResponse(std::move(d), onSuccess, onFailure, std::move(p));
194 },
195 onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000196}
197
198template<typename Dataset>
Davide Pesavento3b101d02018-07-21 22:44:09 -0400199void
Junxiao Shi7357ef22016-09-07 02:39:37 +0000200Controller::processDatasetResponse(shared_ptr<Dataset> dataset,
201 const std::function<void(typename Dataset::ResultType)>& onSuccess,
202 const DatasetFailCallback& onFailure,
203 ConstBufferPtr payload)
204{
205 typename Dataset::ResultType result;
Davide Pesavento3b101d02018-07-21 22:44:09 -0400206
Junxiao Shi7357ef22016-09-07 02:39:37 +0000207 try {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400208 result = dataset->parseResult(std::move(payload));
Junxiao Shi7357ef22016-09-07 02:39:37 +0000209 }
210 catch (const tlv::Error& e) {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400211 if (onFailure)
212 onFailure(ERROR_SERVER, e.what());
Junxiao Shi7357ef22016-09-07 02:39:37 +0000213 return;
214 }
215
Davide Pesavento3b101d02018-07-21 22:44:09 -0400216 if (onSuccess)
217 onSuccess(result);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000218}
219
220} // namespace nfd
221} // namespace ndn
222
223#endif // NDN_MGMT_NFD_CONTROLLER_HPP