blob: 0553df122f3710f027651af98039264bd8f8c458 [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"
Junxiao Shi7357ef22016-09-07 02:39:37 +000033
34namespace ndn {
35
Junxiao Shi7357ef22016-09-07 02:39:37 +000036class Face;
37
38namespace nfd {
39
40/**
41 * \defgroup management Management
42 * \brief Classes and data structures to manage NDN forwarder
43 */
44
45/**
46 * \ingroup management
47 * \brief NFD Management protocol client
48 * \sa https://redmine.named-data.net/projects/nfd/wiki/Management
49 */
50class Controller : noncopyable
51{
52public:
53 /** \brief a callback on command success
54 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040055 using CommandSucceedCallback = function<void(const ControlParameters&)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000056
57 /** \brief a callback on command failure
58 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040059 using CommandFailCallback = function<void(const ControlResponse&)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000060
61 /** \brief a callback on dataset retrieval failure
62 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040063 using DatasetFailCallback = function<void(uint32_t code, const std::string& reason)>;
Junxiao Shi7357ef22016-09-07 02:39:37 +000064
65 /** \brief construct a Controller that uses face for transport,
66 * and uses the passed KeyChain to sign commands
67 */
Davide Pesavento3b101d02018-07-21 22:44:09 -040068 Controller(Face& face, KeyChain& keyChain,
69 security::v2::Validator& validator = security::getAcceptAllValidator());
Junxiao Shi7357ef22016-09-07 02:39:37 +000070
71 /** \brief start command execution
72 */
73 template<typename Command>
74 void
75 start(const ControlParameters& parameters,
76 const CommandSucceedCallback& onSuccess,
77 const CommandFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -070078 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +000079 {
Davide Pesavento3b101d02018-07-21 22:44:09 -040080 startCommand(make_shared<Command>(), parameters, onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +000081 }
82
83 /** \brief start dataset fetching
84 */
85 template<typename Dataset>
Davide Pesaventodb4da5e2018-06-15 11:37:52 -040086 std::enable_if_t<std::is_default_constructible<Dataset>::value>
Junxiao Shi7357ef22016-09-07 02:39:37 +000087 fetch(const std::function<void(typename Dataset::ResultType)>& onSuccess,
88 const DatasetFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -070089 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +000090 {
Davide Pesavento3b101d02018-07-21 22:44:09 -040091 fetchDataset(make_shared<Dataset>(), onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +000092 }
93
94 /** \brief start dataset fetching
95 */
96 template<typename Dataset, typename ParamType = typename Dataset::ParamType>
97 void
98 fetch(const ParamType& param,
99 const std::function<void(typename Dataset::ResultType)>& onSuccess,
100 const DatasetFailCallback& onFailure,
Eric Newberry71a2f032018-06-18 23:49:43 -0700101 const CommandOptions& options = CommandOptions())
Junxiao Shi7357ef22016-09-07 02:39:37 +0000102 {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400103 fetchDataset(make_shared<Dataset>(param), onSuccess, onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000104 }
105
106private:
107 void
108 startCommand(const shared_ptr<ControlCommand>& command,
109 const ControlParameters& parameters,
110 const CommandSucceedCallback& onSuccess,
111 const CommandFailCallback& onFailure,
112 const CommandOptions& options);
113
114 void
115 processCommandResponse(const Data& data,
116 const shared_ptr<ControlCommand>& command,
117 const CommandSucceedCallback& onSuccess,
118 const CommandFailCallback& onFailure);
119
120 void
121 processValidatedCommandResponse(const Data& data,
122 const shared_ptr<ControlCommand>& command,
123 const CommandSucceedCallback& onSuccess,
124 const CommandFailCallback& onFailure);
125
126 template<typename Dataset>
127 void
128 fetchDataset(shared_ptr<Dataset> dataset,
129 const std::function<void(typename Dataset::ResultType)>& onSuccess,
130 const DatasetFailCallback& onFailure,
131 const CommandOptions& options);
132
133 void
134 fetchDataset(const Name& prefix,
Eric Newberrye345baa2018-05-23 18:17:07 -0700135 const std::function<void(ConstBufferPtr)>& processResponse,
Junxiao Shi7357ef22016-09-07 02:39:37 +0000136 const DatasetFailCallback& onFailure,
137 const CommandOptions& options);
138
139 template<typename Dataset>
140 void
141 processDatasetResponse(shared_ptr<Dataset> dataset,
142 const std::function<void(typename Dataset::ResultType)>& onSuccess,
143 const DatasetFailCallback& onFailure,
144 ConstBufferPtr payload);
145
146 void
147 processDatasetFetchError(const DatasetFailCallback& onFailure, uint32_t code, std::string msg);
148
149public:
150 /** \brief error code for timeout
151 */
152 static const uint32_t ERROR_TIMEOUT;
153
154 /** \brief error code for network Nack
155 */
156 static const uint32_t ERROR_NACK;
157
158 /** \brief error code for response validation failure
159 */
160 static const uint32_t ERROR_VALIDATION;
161
162 /** \brief error code for server error
163 */
164 static const uint32_t ERROR_SERVER;
165
166 /** \brief inclusive lower bound of error codes
167 */
168 static const uint32_t ERROR_LBOUND;
169
170protected:
171 Face& m_face;
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800172 KeyChain& m_keyChain;
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -0800173 security::v2::Validator& m_validator;
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800174 security::CommandInterestSigner m_signer;
Junxiao Shi7357ef22016-09-07 02:39:37 +0000175};
176
177template<typename Dataset>
Davide Pesavento3b101d02018-07-21 22:44:09 -0400178void
Junxiao Shi7357ef22016-09-07 02:39:37 +0000179Controller::fetchDataset(shared_ptr<Dataset> dataset,
Davide Pesavento3b101d02018-07-21 22:44:09 -0400180 const std::function<void(typename Dataset::ResultType)>& onSuccess,
181 const DatasetFailCallback& onFailure,
Junxiao Shi7357ef22016-09-07 02:39:37 +0000182 const CommandOptions& options)
183{
Junxiao Shi7357ef22016-09-07 02:39:37 +0000184 Name prefix = dataset->getDatasetPrefix(options.getPrefix());
Davide Pesavento3b101d02018-07-21 22:44:09 -0400185 fetchDataset(prefix,
186 [=, d = std::move(dataset)] (ConstBufferPtr p) {
187 processDatasetResponse(std::move(d), onSuccess, onFailure, std::move(p));
188 },
189 onFailure, options);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000190}
191
192template<typename Dataset>
Davide Pesavento3b101d02018-07-21 22:44:09 -0400193void
Junxiao Shi7357ef22016-09-07 02:39:37 +0000194Controller::processDatasetResponse(shared_ptr<Dataset> dataset,
195 const std::function<void(typename Dataset::ResultType)>& onSuccess,
196 const DatasetFailCallback& onFailure,
197 ConstBufferPtr payload)
198{
199 typename Dataset::ResultType result;
Davide Pesavento3b101d02018-07-21 22:44:09 -0400200
Junxiao Shi7357ef22016-09-07 02:39:37 +0000201 try {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400202 result = dataset->parseResult(std::move(payload));
Junxiao Shi7357ef22016-09-07 02:39:37 +0000203 }
204 catch (const tlv::Error& e) {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400205 if (onFailure)
206 onFailure(ERROR_SERVER, e.what());
Junxiao Shi7357ef22016-09-07 02:39:37 +0000207 return;
208 }
209
Davide Pesavento3b101d02018-07-21 22:44:09 -0400210 if (onSuccess)
211 onSuccess(result);
Junxiao Shi7357ef22016-09-07 02:39:37 +0000212}
213
214} // namespace nfd
215} // namespace ndn
216
217#endif // NDN_MGMT_NFD_CONTROLLER_HPP