blob: 96bba6c20023e203a6b3b2b7df109bd85cdf1fe9 [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)
Eric Newberryda916d62016-08-11 23:04:34 -070099 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
100 .optional(CONTROL_PARAMETER_FLAGS)
101 .optional(CONTROL_PARAMETER_MASK);
Junxiao Shi70911652014-08-12 10:14:24 -0700102 m_responseValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800103 .required(CONTROL_PARAMETER_FACE_ID)
Eric Newberryda916d62016-08-11 23:04:34 -0700104 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
105 .optional(CONTROL_PARAMETER_FLAGS)
106 .optional(CONTROL_PARAMETER_URI);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800107}
108
109void
110FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
111{
112 if (!parameters.hasFacePersistency()) {
113 parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
114 }
Junxiao Shi70911652014-08-12 10:14:24 -0700115}
116
117void
Eric Newberryda916d62016-08-11 23:04:34 -0700118FaceCreateCommand::validateRequest(const ControlParameters& parameters) const
119{
120 this->ControlCommand::validateRequest(parameters);
121
122 if (parameters.hasFlags() != parameters.hasMask()) {
123 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
124 }
125}
126
127void
Junxiao Shi70911652014-08-12 10:14:24 -0700128FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
129{
130 this->ControlCommand::validateResponse(parameters);
131
Davide Pesaventof8503d22017-02-17 01:19:10 -0500132 if (parameters.getFaceId() == INVALID_FACE_ID) {
133 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700134 }
135}
136
Yanbiao Licbdacb22016-08-02 16:02:35 +0800137FaceUpdateCommand::FaceUpdateCommand()
138 : ControlCommand("faces", "update")
139{
140 m_requestValidator
Eric Newberryda916d62016-08-11 23:04:34 -0700141 .optional(CONTROL_PARAMETER_FACE_ID)
142 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
143 .optional(CONTROL_PARAMETER_FLAGS)
144 .optional(CONTROL_PARAMETER_MASK);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800145 m_responseValidator
Eric Newberry138ef2c2016-08-15 20:29:03 -0700146 .required(CONTROL_PARAMETER_FACE_ID)
147 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
148 .required(CONTROL_PARAMETER_FLAGS);
Eric Newberryda916d62016-08-11 23:04:34 -0700149}
150
151void
152FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
153{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700154 if (!parameters.hasFaceId()) {
155 parameters.setFaceId(0);
156 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800157}
158
159void
160FaceUpdateCommand::validateRequest(const ControlParameters& parameters) const
161{
162 this->ControlCommand::validateRequest(parameters);
163
Eric Newberryda916d62016-08-11 23:04:34 -0700164 if (parameters.hasFlags() != parameters.hasMask()) {
165 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
Yanbiao Licbdacb22016-08-02 16:02:35 +0800166 }
167}
168
169void
170FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
171{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700172 this->ControlCommand::validateResponse(parameters);
173
Davide Pesaventof8503d22017-02-17 01:19:10 -0500174 if (parameters.getFaceId() == INVALID_FACE_ID) {
175 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700176 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800177}
178
Junxiao Shi70911652014-08-12 10:14:24 -0700179FaceDestroyCommand::FaceDestroyCommand()
180 : ControlCommand("faces", "destroy")
181{
182 m_requestValidator
183 .required(CONTROL_PARAMETER_FACE_ID);
184 m_responseValidator = m_requestValidator;
185}
186
187void
188FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
189{
190 this->ControlCommand::validateRequest(parameters);
191
Davide Pesaventof8503d22017-02-17 01:19:10 -0500192 if (parameters.getFaceId() == INVALID_FACE_ID) {
193 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700194 }
195}
196
197void
198FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
199{
200 this->validateRequest(parameters);
201}
202
203FaceLocalControlCommand::FaceLocalControlCommand(const std::string& verb)
204 : ControlCommand("faces", verb)
205{
206 m_requestValidator
207 .required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
208 m_responseValidator = m_requestValidator;
209}
210
211void
212FaceLocalControlCommand::validateRequest(const ControlParameters& parameters) const
213{
214 this->ControlCommand::validateRequest(parameters);
215
216 switch (parameters.getLocalControlFeature()) {
217 case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
218 case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
219 break;
220 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700221 BOOST_THROW_EXCEPTION(ArgumentError("LocalControlFeature is invalid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700222 }
223}
224
225void
226FaceLocalControlCommand::validateResponse(const ControlParameters& parameters) const
227{
228 this->validateRequest(parameters);
229}
230
231FaceEnableLocalControlCommand::FaceEnableLocalControlCommand()
232 : FaceLocalControlCommand("enable-local-control")
233{
234}
235
236FaceDisableLocalControlCommand::FaceDisableLocalControlCommand()
237 : FaceLocalControlCommand("disable-local-control")
238{
239}
240
241FibAddNextHopCommand::FibAddNextHopCommand()
242 : ControlCommand("fib", "add-nexthop")
243{
244 m_requestValidator
245 .required(CONTROL_PARAMETER_NAME)
246 .optional(CONTROL_PARAMETER_FACE_ID)
247 .optional(CONTROL_PARAMETER_COST);
248 m_responseValidator
249 .required(CONTROL_PARAMETER_NAME)
250 .required(CONTROL_PARAMETER_FACE_ID)
251 .required(CONTROL_PARAMETER_COST);
252}
253
254void
255FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
256{
257 if (!parameters.hasFaceId()) {
258 parameters.setFaceId(0);
259 }
260 if (!parameters.hasCost()) {
261 parameters.setCost(0);
262 }
263}
264
265void
266FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
267{
268 this->ControlCommand::validateResponse(parameters);
269
Davide Pesaventof8503d22017-02-17 01:19:10 -0500270 if (parameters.getFaceId() == INVALID_FACE_ID) {
271 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700272 }
273}
274
275FibRemoveNextHopCommand::FibRemoveNextHopCommand()
276 : ControlCommand("fib", "remove-nexthop")
277{
278 m_requestValidator
279 .required(CONTROL_PARAMETER_NAME)
280 .optional(CONTROL_PARAMETER_FACE_ID);
281 m_responseValidator
282 .required(CONTROL_PARAMETER_NAME)
283 .required(CONTROL_PARAMETER_FACE_ID);
284}
285
286void
287FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
288{
289 if (!parameters.hasFaceId()) {
290 parameters.setFaceId(0);
291 }
292}
293
294void
295FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
296{
297 this->ControlCommand::validateResponse(parameters);
298
Davide Pesaventof8503d22017-02-17 01:19:10 -0500299 if (parameters.getFaceId() == INVALID_FACE_ID) {
300 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700301 }
302}
303
304StrategyChoiceSetCommand::StrategyChoiceSetCommand()
305 : ControlCommand("strategy-choice", "set")
306{
307 m_requestValidator
308 .required(CONTROL_PARAMETER_NAME)
309 .required(CONTROL_PARAMETER_STRATEGY);
310 m_responseValidator = m_requestValidator;
311}
312
313StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
314 : ControlCommand("strategy-choice", "unset")
315{
316 m_requestValidator
317 .required(CONTROL_PARAMETER_NAME);
318 m_responseValidator = m_requestValidator;
319}
320
321void
322StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
323{
324 this->ControlCommand::validateRequest(parameters);
325
326 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700327 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700328 }
329}
330
331void
332StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
333{
334 this->validateRequest(parameters);
335}
336
337RibRegisterCommand::RibRegisterCommand()
338 : ControlCommand("rib", "register")
339{
340 m_requestValidator
341 .required(CONTROL_PARAMETER_NAME)
342 .optional(CONTROL_PARAMETER_FACE_ID)
343 .optional(CONTROL_PARAMETER_ORIGIN)
344 .optional(CONTROL_PARAMETER_COST)
345 .optional(CONTROL_PARAMETER_FLAGS)
346 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
347 m_responseValidator
348 .required(CONTROL_PARAMETER_NAME)
349 .required(CONTROL_PARAMETER_FACE_ID)
350 .required(CONTROL_PARAMETER_ORIGIN)
351 .required(CONTROL_PARAMETER_COST)
352 .required(CONTROL_PARAMETER_FLAGS)
353 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
354}
355
356void
357RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
358{
359 if (!parameters.hasFaceId()) {
360 parameters.setFaceId(0);
361 }
362 if (!parameters.hasOrigin()) {
363 parameters.setOrigin(ROUTE_ORIGIN_APP);
364 }
365 if (!parameters.hasCost()) {
366 parameters.setCost(0);
367 }
368 if (!parameters.hasFlags()) {
369 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
370 }
371}
372
373void
374RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
375{
376 this->ControlCommand::validateResponse(parameters);
377
Davide Pesaventof8503d22017-02-17 01:19:10 -0500378 if (parameters.getFaceId() == INVALID_FACE_ID) {
379 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700380 }
381}
382
383RibUnregisterCommand::RibUnregisterCommand()
384 : ControlCommand("rib", "unregister")
385{
386 m_requestValidator
387 .required(CONTROL_PARAMETER_NAME)
388 .optional(CONTROL_PARAMETER_FACE_ID)
389 .optional(CONTROL_PARAMETER_ORIGIN);
390 m_responseValidator
391 .required(CONTROL_PARAMETER_NAME)
392 .required(CONTROL_PARAMETER_FACE_ID)
393 .required(CONTROL_PARAMETER_ORIGIN);
394}
395
396void
397RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
398{
399 if (!parameters.hasFaceId()) {
400 parameters.setFaceId(0);
401 }
402 if (!parameters.hasOrigin()) {
403 parameters.setOrigin(ROUTE_ORIGIN_APP);
404 }
405}
406
407void
408RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
409{
410 this->ControlCommand::validateResponse(parameters);
411
Davide Pesaventof8503d22017-02-17 01:19:10 -0500412 if (parameters.getFaceId() == INVALID_FACE_ID) {
413 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700414 }
415}
416
417} // namespace nfd
418} // namespace ndn