blob: de840d63f46d6850e7ed8c05b8b7615f14bb1ea4 [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)
Junxiao Shi144c7e32017-04-20 01:04:06 +0000107 .optional(CONTROL_PARAMETER_URI)
108 .optional(CONTROL_PARAMETER_LOCAL_URI);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800109}
110
111void
112FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
113{
114 if (!parameters.hasFacePersistency()) {
115 parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
116 }
Junxiao Shi70911652014-08-12 10:14:24 -0700117}
118
119void
Eric Newberryda916d62016-08-11 23:04:34 -0700120FaceCreateCommand::validateRequest(const ControlParameters& parameters) const
121{
122 this->ControlCommand::validateRequest(parameters);
123
124 if (parameters.hasFlags() != parameters.hasMask()) {
125 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
126 }
127}
128
129void
Junxiao Shi70911652014-08-12 10:14:24 -0700130FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
131{
132 this->ControlCommand::validateResponse(parameters);
133
Davide Pesaventof8503d22017-02-17 01:19:10 -0500134 if (parameters.getFaceId() == INVALID_FACE_ID) {
135 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700136 }
137}
138
Yanbiao Licbdacb22016-08-02 16:02:35 +0800139FaceUpdateCommand::FaceUpdateCommand()
140 : ControlCommand("faces", "update")
141{
142 m_requestValidator
Eric Newberryda916d62016-08-11 23:04:34 -0700143 .optional(CONTROL_PARAMETER_FACE_ID)
144 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
145 .optional(CONTROL_PARAMETER_FLAGS)
146 .optional(CONTROL_PARAMETER_MASK);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800147 m_responseValidator
Eric Newberry138ef2c2016-08-15 20:29:03 -0700148 .required(CONTROL_PARAMETER_FACE_ID)
149 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
150 .required(CONTROL_PARAMETER_FLAGS);
Eric Newberryda916d62016-08-11 23:04:34 -0700151}
152
153void
154FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
155{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700156 if (!parameters.hasFaceId()) {
157 parameters.setFaceId(0);
158 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800159}
160
161void
162FaceUpdateCommand::validateRequest(const ControlParameters& parameters) const
163{
164 this->ControlCommand::validateRequest(parameters);
165
Eric Newberryda916d62016-08-11 23:04:34 -0700166 if (parameters.hasFlags() != parameters.hasMask()) {
167 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
Yanbiao Licbdacb22016-08-02 16:02:35 +0800168 }
169}
170
171void
172FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
173{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700174 this->ControlCommand::validateResponse(parameters);
175
Davide Pesaventof8503d22017-02-17 01:19:10 -0500176 if (parameters.getFaceId() == INVALID_FACE_ID) {
177 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700178 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800179}
180
Junxiao Shi70911652014-08-12 10:14:24 -0700181FaceDestroyCommand::FaceDestroyCommand()
182 : ControlCommand("faces", "destroy")
183{
184 m_requestValidator
185 .required(CONTROL_PARAMETER_FACE_ID);
186 m_responseValidator = m_requestValidator;
187}
188
189void
190FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
191{
192 this->ControlCommand::validateRequest(parameters);
193
Davide Pesaventof8503d22017-02-17 01:19:10 -0500194 if (parameters.getFaceId() == INVALID_FACE_ID) {
195 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700196 }
197}
198
199void
200FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
201{
202 this->validateRequest(parameters);
203}
204
205FaceLocalControlCommand::FaceLocalControlCommand(const std::string& verb)
206 : ControlCommand("faces", verb)
207{
208 m_requestValidator
209 .required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
210 m_responseValidator = m_requestValidator;
211}
212
213void
214FaceLocalControlCommand::validateRequest(const ControlParameters& parameters) const
215{
216 this->ControlCommand::validateRequest(parameters);
217
218 switch (parameters.getLocalControlFeature()) {
219 case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
220 case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
221 break;
222 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700223 BOOST_THROW_EXCEPTION(ArgumentError("LocalControlFeature is invalid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700224 }
225}
226
227void
228FaceLocalControlCommand::validateResponse(const ControlParameters& parameters) const
229{
230 this->validateRequest(parameters);
231}
232
233FaceEnableLocalControlCommand::FaceEnableLocalControlCommand()
234 : FaceLocalControlCommand("enable-local-control")
235{
236}
237
238FaceDisableLocalControlCommand::FaceDisableLocalControlCommand()
239 : FaceLocalControlCommand("disable-local-control")
240{
241}
242
243FibAddNextHopCommand::FibAddNextHopCommand()
244 : ControlCommand("fib", "add-nexthop")
245{
246 m_requestValidator
247 .required(CONTROL_PARAMETER_NAME)
248 .optional(CONTROL_PARAMETER_FACE_ID)
249 .optional(CONTROL_PARAMETER_COST);
250 m_responseValidator
251 .required(CONTROL_PARAMETER_NAME)
252 .required(CONTROL_PARAMETER_FACE_ID)
253 .required(CONTROL_PARAMETER_COST);
254}
255
256void
257FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
258{
259 if (!parameters.hasFaceId()) {
260 parameters.setFaceId(0);
261 }
262 if (!parameters.hasCost()) {
263 parameters.setCost(0);
264 }
265}
266
267void
268FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
269{
270 this->ControlCommand::validateResponse(parameters);
271
Davide Pesaventof8503d22017-02-17 01:19:10 -0500272 if (parameters.getFaceId() == INVALID_FACE_ID) {
273 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700274 }
275}
276
277FibRemoveNextHopCommand::FibRemoveNextHopCommand()
278 : ControlCommand("fib", "remove-nexthop")
279{
280 m_requestValidator
281 .required(CONTROL_PARAMETER_NAME)
282 .optional(CONTROL_PARAMETER_FACE_ID);
283 m_responseValidator
284 .required(CONTROL_PARAMETER_NAME)
285 .required(CONTROL_PARAMETER_FACE_ID);
286}
287
288void
289FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
290{
291 if (!parameters.hasFaceId()) {
292 parameters.setFaceId(0);
293 }
294}
295
296void
297FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
298{
299 this->ControlCommand::validateResponse(parameters);
300
Davide Pesaventof8503d22017-02-17 01:19:10 -0500301 if (parameters.getFaceId() == INVALID_FACE_ID) {
302 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700303 }
304}
305
306StrategyChoiceSetCommand::StrategyChoiceSetCommand()
307 : ControlCommand("strategy-choice", "set")
308{
309 m_requestValidator
310 .required(CONTROL_PARAMETER_NAME)
311 .required(CONTROL_PARAMETER_STRATEGY);
312 m_responseValidator = m_requestValidator;
313}
314
315StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
316 : ControlCommand("strategy-choice", "unset")
317{
318 m_requestValidator
319 .required(CONTROL_PARAMETER_NAME);
320 m_responseValidator = m_requestValidator;
321}
322
323void
324StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
325{
326 this->ControlCommand::validateRequest(parameters);
327
328 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700329 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700330 }
331}
332
333void
334StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
335{
336 this->validateRequest(parameters);
337}
338
339RibRegisterCommand::RibRegisterCommand()
340 : ControlCommand("rib", "register")
341{
342 m_requestValidator
343 .required(CONTROL_PARAMETER_NAME)
344 .optional(CONTROL_PARAMETER_FACE_ID)
345 .optional(CONTROL_PARAMETER_ORIGIN)
346 .optional(CONTROL_PARAMETER_COST)
347 .optional(CONTROL_PARAMETER_FLAGS)
348 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
349 m_responseValidator
350 .required(CONTROL_PARAMETER_NAME)
351 .required(CONTROL_PARAMETER_FACE_ID)
352 .required(CONTROL_PARAMETER_ORIGIN)
353 .required(CONTROL_PARAMETER_COST)
354 .required(CONTROL_PARAMETER_FLAGS)
355 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
356}
357
358void
359RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
360{
361 if (!parameters.hasFaceId()) {
362 parameters.setFaceId(0);
363 }
364 if (!parameters.hasOrigin()) {
365 parameters.setOrigin(ROUTE_ORIGIN_APP);
366 }
367 if (!parameters.hasCost()) {
368 parameters.setCost(0);
369 }
370 if (!parameters.hasFlags()) {
371 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
372 }
373}
374
375void
376RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
377{
378 this->ControlCommand::validateResponse(parameters);
379
Davide Pesaventof8503d22017-02-17 01:19:10 -0500380 if (parameters.getFaceId() == INVALID_FACE_ID) {
381 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700382 }
383}
384
385RibUnregisterCommand::RibUnregisterCommand()
386 : ControlCommand("rib", "unregister")
387{
388 m_requestValidator
389 .required(CONTROL_PARAMETER_NAME)
390 .optional(CONTROL_PARAMETER_FACE_ID)
391 .optional(CONTROL_PARAMETER_ORIGIN);
392 m_responseValidator
393 .required(CONTROL_PARAMETER_NAME)
394 .required(CONTROL_PARAMETER_FACE_ID)
395 .required(CONTROL_PARAMETER_ORIGIN);
396}
397
398void
399RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
400{
401 if (!parameters.hasFaceId()) {
402 parameters.setFaceId(0);
403 }
404 if (!parameters.hasOrigin()) {
405 parameters.setOrigin(ROUTE_ORIGIN_APP);
406 }
407}
408
409void
410RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
411{
412 this->ControlCommand::validateResponse(parameters);
413
Davide Pesaventof8503d22017-02-17 01:19:10 -0500414 if (parameters.getFaceId() == INVALID_FACE_ID) {
415 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700416 }
417}
418
419} // namespace nfd
420} // namespace ndn