blob: a51ecb6b4e88d0ab6fdb9dd24dc5ba7b74198e5e [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesaventof8503d22017-02-17 01:19:10 -05003 * Copyright (c) 2013-2017 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"
23#include "command-options.hpp" // only used in deprecated functions
Junxiao Shi70911652014-08-12 10:14:24 -070024
25namespace ndn {
26namespace nfd {
27
28ControlCommand::ControlCommand(const std::string& module, const std::string& verb)
Junxiao Shi5de006b2014-10-26 20:20:52 -070029 : m_module(module)
30 , m_verb(verb)
Junxiao Shi70911652014-08-12 10:14:24 -070031{
Junxiao Shi70911652014-08-12 10:14:24 -070032}
33
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020034ControlCommand::~ControlCommand() = default;
35
Junxiao Shi70911652014-08-12 10:14:24 -070036void
37ControlCommand::validateRequest(const ControlParameters& parameters) const
38{
39 m_requestValidator.validate(parameters);
40}
41
42void
43ControlCommand::applyDefaultsToRequest(ControlParameters& parameters) const
44{
45}
46
47void
48ControlCommand::validateResponse(const ControlParameters& parameters) const
49{
50 m_responseValidator.validate(parameters);
51}
52
53void
54ControlCommand::applyDefaultsToResponse(ControlParameters& parameters) const
55{
56}
57
58Name
Junxiao Shi5de006b2014-10-26 20:20:52 -070059ControlCommand::getRequestName(const Name& commandPrefix,
60 const ControlParameters& parameters) const
Junxiao Shi70911652014-08-12 10:14:24 -070061{
62 this->validateRequest(parameters);
63
Junxiao Shi5de006b2014-10-26 20:20:52 -070064 Name name = commandPrefix;
65 name.append(m_module).append(m_verb);
Junxiao Shi70911652014-08-12 10:14:24 -070066 name.append(parameters.wireEncode());
67 return name;
68}
69
Junxiao Shi70911652014-08-12 10:14:24 -070070ControlCommand::FieldValidator::FieldValidator()
71 : m_required(CONTROL_PARAMETER_UBOUND)
72 , m_optional(CONTROL_PARAMETER_UBOUND)
73{
74}
75
76void
77ControlCommand::FieldValidator::validate(const ControlParameters& parameters) const
78{
79 const std::vector<bool>& presentFields = parameters.getPresentFields();
80
81 for (size_t i = 0; i < CONTROL_PARAMETER_UBOUND; ++i) {
82 bool isPresent = presentFields[i];
83 if (m_required[i]) {
84 if (!isPresent) {
Davide Pesaventof8503d22017-02-17 01:19:10 -050085 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
Junxiao Shi70911652014-08-12 10:14:24 -070086 }
87 }
88 else if (isPresent && !m_optional[i]) {
Davide Pesaventof8503d22017-02-17 01:19:10 -050089 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
Junxiao Shi70911652014-08-12 10:14:24 -070090 }
91 }
92}
93
94FaceCreateCommand::FaceCreateCommand()
95 : ControlCommand("faces", "create")
96{
97 m_requestValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +080098 .required(CONTROL_PARAMETER_URI)
Teng Liangf4908b12017-03-29 15:24:03 -070099 .optional(CONTROL_PARAMETER_LOCAL_URI)
Eric Newberryda916d62016-08-11 23:04:34 -0700100 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
101 .optional(CONTROL_PARAMETER_FLAGS)
102 .optional(CONTROL_PARAMETER_MASK);
Junxiao Shi70911652014-08-12 10:14:24 -0700103 m_responseValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800104 .required(CONTROL_PARAMETER_FACE_ID)
Eric Newberryda916d62016-08-11 23:04:34 -0700105 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
106 .optional(CONTROL_PARAMETER_FLAGS)
107 .optional(CONTROL_PARAMETER_URI);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800108}
109
110void
111FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
112{
113 if (!parameters.hasFacePersistency()) {
114 parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
115 }
Junxiao Shi70911652014-08-12 10:14:24 -0700116}
117
118void
Eric Newberryda916d62016-08-11 23:04:34 -0700119FaceCreateCommand::validateRequest(const ControlParameters& parameters) const
120{
121 this->ControlCommand::validateRequest(parameters);
122
123 if (parameters.hasFlags() != parameters.hasMask()) {
124 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
125 }
126}
127
128void
Junxiao Shi70911652014-08-12 10:14:24 -0700129FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
130{
131 this->ControlCommand::validateResponse(parameters);
132
Davide Pesaventof8503d22017-02-17 01:19:10 -0500133 if (parameters.getFaceId() == INVALID_FACE_ID) {
134 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700135 }
136}
137
Yanbiao Licbdacb22016-08-02 16:02:35 +0800138FaceUpdateCommand::FaceUpdateCommand()
139 : ControlCommand("faces", "update")
140{
141 m_requestValidator
Eric Newberryda916d62016-08-11 23:04:34 -0700142 .optional(CONTROL_PARAMETER_FACE_ID)
143 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
144 .optional(CONTROL_PARAMETER_FLAGS)
145 .optional(CONTROL_PARAMETER_MASK);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800146 m_responseValidator
Eric Newberry138ef2c2016-08-15 20:29:03 -0700147 .required(CONTROL_PARAMETER_FACE_ID)
148 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
149 .required(CONTROL_PARAMETER_FLAGS);
Eric Newberryda916d62016-08-11 23:04:34 -0700150}
151
152void
153FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
154{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700155 if (!parameters.hasFaceId()) {
156 parameters.setFaceId(0);
157 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800158}
159
160void
161FaceUpdateCommand::validateRequest(const ControlParameters& parameters) const
162{
163 this->ControlCommand::validateRequest(parameters);
164
Eric Newberryda916d62016-08-11 23:04:34 -0700165 if (parameters.hasFlags() != parameters.hasMask()) {
166 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
Yanbiao Licbdacb22016-08-02 16:02:35 +0800167 }
168}
169
170void
171FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
172{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700173 this->ControlCommand::validateResponse(parameters);
174
Davide Pesaventof8503d22017-02-17 01:19:10 -0500175 if (parameters.getFaceId() == INVALID_FACE_ID) {
176 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700177 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800178}
179
Junxiao Shi70911652014-08-12 10:14:24 -0700180FaceDestroyCommand::FaceDestroyCommand()
181 : ControlCommand("faces", "destroy")
182{
183 m_requestValidator
184 .required(CONTROL_PARAMETER_FACE_ID);
185 m_responseValidator = m_requestValidator;
186}
187
188void
189FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
190{
191 this->ControlCommand::validateRequest(parameters);
192
Davide Pesaventof8503d22017-02-17 01:19:10 -0500193 if (parameters.getFaceId() == INVALID_FACE_ID) {
194 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700195 }
196}
197
198void
199FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
200{
201 this->validateRequest(parameters);
202}
203
204FaceLocalControlCommand::FaceLocalControlCommand(const std::string& verb)
205 : ControlCommand("faces", verb)
206{
207 m_requestValidator
208 .required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
209 m_responseValidator = m_requestValidator;
210}
211
212void
213FaceLocalControlCommand::validateRequest(const ControlParameters& parameters) const
214{
215 this->ControlCommand::validateRequest(parameters);
216
217 switch (parameters.getLocalControlFeature()) {
218 case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
219 case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
220 break;
221 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700222 BOOST_THROW_EXCEPTION(ArgumentError("LocalControlFeature is invalid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700223 }
224}
225
226void
227FaceLocalControlCommand::validateResponse(const ControlParameters& parameters) const
228{
229 this->validateRequest(parameters);
230}
231
232FaceEnableLocalControlCommand::FaceEnableLocalControlCommand()
233 : FaceLocalControlCommand("enable-local-control")
234{
235}
236
237FaceDisableLocalControlCommand::FaceDisableLocalControlCommand()
238 : FaceLocalControlCommand("disable-local-control")
239{
240}
241
242FibAddNextHopCommand::FibAddNextHopCommand()
243 : ControlCommand("fib", "add-nexthop")
244{
245 m_requestValidator
246 .required(CONTROL_PARAMETER_NAME)
247 .optional(CONTROL_PARAMETER_FACE_ID)
248 .optional(CONTROL_PARAMETER_COST);
249 m_responseValidator
250 .required(CONTROL_PARAMETER_NAME)
251 .required(CONTROL_PARAMETER_FACE_ID)
252 .required(CONTROL_PARAMETER_COST);
253}
254
255void
256FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
257{
258 if (!parameters.hasFaceId()) {
259 parameters.setFaceId(0);
260 }
261 if (!parameters.hasCost()) {
262 parameters.setCost(0);
263 }
264}
265
266void
267FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
268{
269 this->ControlCommand::validateResponse(parameters);
270
Davide Pesaventof8503d22017-02-17 01:19:10 -0500271 if (parameters.getFaceId() == INVALID_FACE_ID) {
272 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700273 }
274}
275
276FibRemoveNextHopCommand::FibRemoveNextHopCommand()
277 : ControlCommand("fib", "remove-nexthop")
278{
279 m_requestValidator
280 .required(CONTROL_PARAMETER_NAME)
281 .optional(CONTROL_PARAMETER_FACE_ID);
282 m_responseValidator
283 .required(CONTROL_PARAMETER_NAME)
284 .required(CONTROL_PARAMETER_FACE_ID);
285}
286
287void
288FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
289{
290 if (!parameters.hasFaceId()) {
291 parameters.setFaceId(0);
292 }
293}
294
295void
296FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
297{
298 this->ControlCommand::validateResponse(parameters);
299
Davide Pesaventof8503d22017-02-17 01:19:10 -0500300 if (parameters.getFaceId() == INVALID_FACE_ID) {
301 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700302 }
303}
304
305StrategyChoiceSetCommand::StrategyChoiceSetCommand()
306 : ControlCommand("strategy-choice", "set")
307{
308 m_requestValidator
309 .required(CONTROL_PARAMETER_NAME)
310 .required(CONTROL_PARAMETER_STRATEGY);
311 m_responseValidator = m_requestValidator;
312}
313
314StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
315 : ControlCommand("strategy-choice", "unset")
316{
317 m_requestValidator
318 .required(CONTROL_PARAMETER_NAME);
319 m_responseValidator = m_requestValidator;
320}
321
322void
323StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
324{
325 this->ControlCommand::validateRequest(parameters);
326
327 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700328 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700329 }
330}
331
332void
333StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
334{
335 this->validateRequest(parameters);
336}
337
338RibRegisterCommand::RibRegisterCommand()
339 : ControlCommand("rib", "register")
340{
341 m_requestValidator
342 .required(CONTROL_PARAMETER_NAME)
343 .optional(CONTROL_PARAMETER_FACE_ID)
344 .optional(CONTROL_PARAMETER_ORIGIN)
345 .optional(CONTROL_PARAMETER_COST)
346 .optional(CONTROL_PARAMETER_FLAGS)
347 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
348 m_responseValidator
349 .required(CONTROL_PARAMETER_NAME)
350 .required(CONTROL_PARAMETER_FACE_ID)
351 .required(CONTROL_PARAMETER_ORIGIN)
352 .required(CONTROL_PARAMETER_COST)
353 .required(CONTROL_PARAMETER_FLAGS)
354 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
355}
356
357void
358RibRegisterCommand::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 if (!parameters.hasCost()) {
367 parameters.setCost(0);
368 }
369 if (!parameters.hasFlags()) {
370 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
371 }
372}
373
374void
375RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
376{
377 this->ControlCommand::validateResponse(parameters);
378
Davide Pesaventof8503d22017-02-17 01:19:10 -0500379 if (parameters.getFaceId() == INVALID_FACE_ID) {
380 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700381 }
382}
383
384RibUnregisterCommand::RibUnregisterCommand()
385 : ControlCommand("rib", "unregister")
386{
387 m_requestValidator
388 .required(CONTROL_PARAMETER_NAME)
389 .optional(CONTROL_PARAMETER_FACE_ID)
390 .optional(CONTROL_PARAMETER_ORIGIN);
391 m_responseValidator
392 .required(CONTROL_PARAMETER_NAME)
393 .required(CONTROL_PARAMETER_FACE_ID)
394 .required(CONTROL_PARAMETER_ORIGIN);
395}
396
397void
398RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
399{
400 if (!parameters.hasFaceId()) {
401 parameters.setFaceId(0);
402 }
403 if (!parameters.hasOrigin()) {
404 parameters.setOrigin(ROUTE_ORIGIN_APP);
405 }
406}
407
408void
409RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
410{
411 this->ControlCommand::validateResponse(parameters);
412
Davide Pesaventof8503d22017-02-17 01:19:10 -0500413 if (parameters.getFaceId() == INVALID_FACE_ID) {
414 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700415 }
416}
417
418} // namespace nfd
419} // namespace ndn