blob: f85c8707e81756e9b681f526e719c4e58e4832c3 [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi22f85682018-01-22 19:23:22 +00002/*
3 * Copyright (c) 2013-2018 Regents of the University of California.
Junxiao Shi70911652014-08-12 10:14:24 -07004 *
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
Junxiao Shi7357ef22016-09-07 02:39:37 +000022#include "control-command.hpp"
Junxiao Shi70911652014-08-12 10:14:24 -070023
24namespace ndn {
25namespace nfd {
26
27ControlCommand::ControlCommand(const std::string& module, const std::string& verb)
Junxiao Shi5de006b2014-10-26 20:20:52 -070028 : m_module(module)
29 , m_verb(verb)
Junxiao Shi70911652014-08-12 10:14:24 -070030{
Junxiao Shi70911652014-08-12 10:14:24 -070031}
32
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020033ControlCommand::~ControlCommand() = default;
34
Junxiao Shi70911652014-08-12 10:14:24 -070035void
36ControlCommand::validateRequest(const ControlParameters& parameters) const
37{
38 m_requestValidator.validate(parameters);
39}
40
41void
42ControlCommand::applyDefaultsToRequest(ControlParameters& parameters) const
43{
44}
45
46void
47ControlCommand::validateResponse(const ControlParameters& parameters) const
48{
49 m_responseValidator.validate(parameters);
50}
51
52void
53ControlCommand::applyDefaultsToResponse(ControlParameters& parameters) const
54{
55}
56
57Name
Junxiao Shi5de006b2014-10-26 20:20:52 -070058ControlCommand::getRequestName(const Name& commandPrefix,
59 const ControlParameters& parameters) const
Junxiao Shi70911652014-08-12 10:14:24 -070060{
61 this->validateRequest(parameters);
62
Junxiao Shi5de006b2014-10-26 20:20:52 -070063 Name name = commandPrefix;
64 name.append(m_module).append(m_verb);
Junxiao Shi70911652014-08-12 10:14:24 -070065 name.append(parameters.wireEncode());
66 return name;
67}
68
Junxiao Shi70911652014-08-12 10:14:24 -070069ControlCommand::FieldValidator::FieldValidator()
70 : m_required(CONTROL_PARAMETER_UBOUND)
71 , m_optional(CONTROL_PARAMETER_UBOUND)
72{
73}
74
75void
76ControlCommand::FieldValidator::validate(const ControlParameters& parameters) const
77{
78 const std::vector<bool>& presentFields = parameters.getPresentFields();
79
80 for (size_t i = 0; i < CONTROL_PARAMETER_UBOUND; ++i) {
81 bool isPresent = presentFields[i];
82 if (m_required[i]) {
83 if (!isPresent) {
Davide Pesaventof8503d22017-02-17 01:19:10 -050084 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
Junxiao Shi70911652014-08-12 10:14:24 -070085 }
86 }
87 else if (isPresent && !m_optional[i]) {
Davide Pesaventof8503d22017-02-17 01:19:10 -050088 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
Junxiao Shi70911652014-08-12 10:14:24 -070089 }
90 }
Junxiao Shi22f85682018-01-22 19:23:22 +000091
92 if (m_optional[CONTROL_PARAMETER_FLAGS] && m_optional[CONTROL_PARAMETER_MASK]) {
93 if (parameters.hasFlags() != parameters.hasMask()) {
94 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
95 }
96 }
Junxiao Shi70911652014-08-12 10:14:24 -070097}
98
99FaceCreateCommand::FaceCreateCommand()
100 : ControlCommand("faces", "create")
101{
102 m_requestValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800103 .required(CONTROL_PARAMETER_URI)
Teng Liangf4908b12017-03-29 15:24:03 -0700104 .optional(CONTROL_PARAMETER_LOCAL_URI)
Eric Newberryda916d62016-08-11 23:04:34 -0700105 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
106 .optional(CONTROL_PARAMETER_FLAGS)
107 .optional(CONTROL_PARAMETER_MASK);
Junxiao Shi70911652014-08-12 10:14:24 -0700108 m_responseValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800109 .required(CONTROL_PARAMETER_FACE_ID)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000110 .required(CONTROL_PARAMETER_URI)
111 .required(CONTROL_PARAMETER_LOCAL_URI)
Eric Newberryda916d62016-08-11 23:04:34 -0700112 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000113 .required(CONTROL_PARAMETER_FLAGS);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800114}
115
116void
117FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
118{
119 if (!parameters.hasFacePersistency()) {
120 parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
121 }
Junxiao Shi70911652014-08-12 10:14:24 -0700122}
123
124void
125FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
126{
127 this->ControlCommand::validateResponse(parameters);
128
Davide Pesaventof8503d22017-02-17 01:19:10 -0500129 if (parameters.getFaceId() == INVALID_FACE_ID) {
130 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700131 }
132}
133
Yanbiao Licbdacb22016-08-02 16:02:35 +0800134FaceUpdateCommand::FaceUpdateCommand()
135 : ControlCommand("faces", "update")
136{
137 m_requestValidator
Eric Newberryda916d62016-08-11 23:04:34 -0700138 .optional(CONTROL_PARAMETER_FACE_ID)
139 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
140 .optional(CONTROL_PARAMETER_FLAGS)
141 .optional(CONTROL_PARAMETER_MASK);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800142 m_responseValidator
Eric Newberry138ef2c2016-08-15 20:29:03 -0700143 .required(CONTROL_PARAMETER_FACE_ID)
144 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
145 .required(CONTROL_PARAMETER_FLAGS);
Eric Newberryda916d62016-08-11 23:04:34 -0700146}
147
148void
149FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
150{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700151 if (!parameters.hasFaceId()) {
152 parameters.setFaceId(0);
153 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800154}
155
156void
Yanbiao Licbdacb22016-08-02 16:02:35 +0800157FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
158{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700159 this->ControlCommand::validateResponse(parameters);
160
Davide Pesaventof8503d22017-02-17 01:19:10 -0500161 if (parameters.getFaceId() == INVALID_FACE_ID) {
162 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700163 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800164}
165
Junxiao Shi70911652014-08-12 10:14:24 -0700166FaceDestroyCommand::FaceDestroyCommand()
167 : ControlCommand("faces", "destroy")
168{
169 m_requestValidator
170 .required(CONTROL_PARAMETER_FACE_ID);
171 m_responseValidator = m_requestValidator;
172}
173
174void
175FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
176{
177 this->ControlCommand::validateRequest(parameters);
178
Davide Pesaventof8503d22017-02-17 01:19:10 -0500179 if (parameters.getFaceId() == INVALID_FACE_ID) {
180 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700181 }
182}
183
184void
185FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
186{
187 this->validateRequest(parameters);
188}
189
Junxiao Shi70911652014-08-12 10:14:24 -0700190FibAddNextHopCommand::FibAddNextHopCommand()
191 : ControlCommand("fib", "add-nexthop")
192{
193 m_requestValidator
194 .required(CONTROL_PARAMETER_NAME)
195 .optional(CONTROL_PARAMETER_FACE_ID)
196 .optional(CONTROL_PARAMETER_COST);
197 m_responseValidator
198 .required(CONTROL_PARAMETER_NAME)
199 .required(CONTROL_PARAMETER_FACE_ID)
200 .required(CONTROL_PARAMETER_COST);
201}
202
203void
204FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
205{
206 if (!parameters.hasFaceId()) {
207 parameters.setFaceId(0);
208 }
209 if (!parameters.hasCost()) {
210 parameters.setCost(0);
211 }
212}
213
214void
215FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
216{
217 this->ControlCommand::validateResponse(parameters);
218
Davide Pesaventof8503d22017-02-17 01:19:10 -0500219 if (parameters.getFaceId() == INVALID_FACE_ID) {
220 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700221 }
222}
223
224FibRemoveNextHopCommand::FibRemoveNextHopCommand()
225 : ControlCommand("fib", "remove-nexthop")
226{
227 m_requestValidator
228 .required(CONTROL_PARAMETER_NAME)
229 .optional(CONTROL_PARAMETER_FACE_ID);
230 m_responseValidator
231 .required(CONTROL_PARAMETER_NAME)
232 .required(CONTROL_PARAMETER_FACE_ID);
233}
234
235void
236FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
237{
238 if (!parameters.hasFaceId()) {
239 parameters.setFaceId(0);
240 }
241}
242
243void
244FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
245{
246 this->ControlCommand::validateResponse(parameters);
247
Davide Pesaventof8503d22017-02-17 01:19:10 -0500248 if (parameters.getFaceId() == INVALID_FACE_ID) {
249 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700250 }
251}
252
Junxiao Shi22f85682018-01-22 19:23:22 +0000253CsConfigCommand::CsConfigCommand()
254 : ControlCommand("cs", "config")
255{
256 m_requestValidator
257 .optional(CONTROL_PARAMETER_CAPACITY)
258 .optional(CONTROL_PARAMETER_FLAGS)
259 .optional(CONTROL_PARAMETER_MASK);
260 m_responseValidator
261 .required(CONTROL_PARAMETER_CAPACITY)
262 .required(CONTROL_PARAMETER_FLAGS);
263}
264
Junxiao Shi70911652014-08-12 10:14:24 -0700265StrategyChoiceSetCommand::StrategyChoiceSetCommand()
266 : ControlCommand("strategy-choice", "set")
267{
268 m_requestValidator
269 .required(CONTROL_PARAMETER_NAME)
270 .required(CONTROL_PARAMETER_STRATEGY);
271 m_responseValidator = m_requestValidator;
272}
273
274StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
275 : ControlCommand("strategy-choice", "unset")
276{
277 m_requestValidator
278 .required(CONTROL_PARAMETER_NAME);
279 m_responseValidator = m_requestValidator;
280}
281
282void
283StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
284{
285 this->ControlCommand::validateRequest(parameters);
286
287 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700288 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700289 }
290}
291
292void
293StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
294{
295 this->validateRequest(parameters);
296}
297
298RibRegisterCommand::RibRegisterCommand()
299 : ControlCommand("rib", "register")
300{
301 m_requestValidator
302 .required(CONTROL_PARAMETER_NAME)
303 .optional(CONTROL_PARAMETER_FACE_ID)
304 .optional(CONTROL_PARAMETER_ORIGIN)
305 .optional(CONTROL_PARAMETER_COST)
306 .optional(CONTROL_PARAMETER_FLAGS)
307 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
308 m_responseValidator
309 .required(CONTROL_PARAMETER_NAME)
310 .required(CONTROL_PARAMETER_FACE_ID)
311 .required(CONTROL_PARAMETER_ORIGIN)
312 .required(CONTROL_PARAMETER_COST)
313 .required(CONTROL_PARAMETER_FLAGS)
314 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
315}
316
317void
318RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
319{
320 if (!parameters.hasFaceId()) {
321 parameters.setFaceId(0);
322 }
323 if (!parameters.hasOrigin()) {
324 parameters.setOrigin(ROUTE_ORIGIN_APP);
325 }
326 if (!parameters.hasCost()) {
327 parameters.setCost(0);
328 }
329 if (!parameters.hasFlags()) {
330 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
331 }
332}
333
334void
335RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
336{
337 this->ControlCommand::validateResponse(parameters);
338
Davide Pesaventof8503d22017-02-17 01:19:10 -0500339 if (parameters.getFaceId() == INVALID_FACE_ID) {
340 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700341 }
342}
343
344RibUnregisterCommand::RibUnregisterCommand()
345 : ControlCommand("rib", "unregister")
346{
347 m_requestValidator
348 .required(CONTROL_PARAMETER_NAME)
349 .optional(CONTROL_PARAMETER_FACE_ID)
350 .optional(CONTROL_PARAMETER_ORIGIN);
351 m_responseValidator
352 .required(CONTROL_PARAMETER_NAME)
353 .required(CONTROL_PARAMETER_FACE_ID)
354 .required(CONTROL_PARAMETER_ORIGIN);
355}
356
357void
358RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
359{
360 if (!parameters.hasFaceId()) {
361 parameters.setFaceId(0);
362 }
363 if (!parameters.hasOrigin()) {
364 parameters.setOrigin(ROUTE_ORIGIN_APP);
365 }
366}
367
368void
369RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
370{
371 this->ControlCommand::validateResponse(parameters);
372
Davide Pesaventof8503d22017-02-17 01:19:10 -0500373 if (parameters.getFaceId() == INVALID_FACE_ID) {
374 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700375 }
376}
377
378} // namespace nfd
379} // namespace ndn