blob: 2a6eda7f8846e10af90d4f997c964a4d6aad0b0b [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yanbiao Licbdacb22016-08-02 16:02:35 +08003 * Copyright (c) 2013-2016 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) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070085 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but "
86 "missing"));
Junxiao Shi70911652014-08-12 10:14:24 -070087 }
88 }
89 else if (isPresent && !m_optional[i]) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070090 BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but "
91 "present"));
Junxiao Shi70911652014-08-12 10:14:24 -070092 }
93 }
94}
95
96FaceCreateCommand::FaceCreateCommand()
97 : ControlCommand("faces", "create")
98{
99 m_requestValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800100 .required(CONTROL_PARAMETER_URI)
Eric Newberryda916d62016-08-11 23:04:34 -0700101 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
102 .optional(CONTROL_PARAMETER_FLAGS)
103 .optional(CONTROL_PARAMETER_MASK);
Junxiao Shi70911652014-08-12 10:14:24 -0700104 m_responseValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +0800105 .required(CONTROL_PARAMETER_FACE_ID)
Eric Newberryda916d62016-08-11 23:04:34 -0700106 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
107 .optional(CONTROL_PARAMETER_FLAGS)
108 .optional(CONTROL_PARAMETER_URI);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800109}
110
111void
112FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
113{
Eric Newberryda916d62016-08-11 23:04:34 -0700114 parameters.setFaceId(0);
115
Yukai Tud93c5fc2015-08-25 11:37:16 +0800116 if (!parameters.hasFacePersistency()) {
117 parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
118 }
Junxiao Shi70911652014-08-12 10:14:24 -0700119}
120
121void
Eric Newberryda916d62016-08-11 23:04:34 -0700122FaceCreateCommand::validateRequest(const ControlParameters& parameters) const
123{
124 this->ControlCommand::validateRequest(parameters);
125
126 if (parameters.hasFlags() != parameters.hasMask()) {
127 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
128 }
129}
130
131void
Junxiao Shi70911652014-08-12 10:14:24 -0700132FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
133{
134 this->ControlCommand::validateResponse(parameters);
135
136 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700137 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700138 }
139}
140
Yanbiao Licbdacb22016-08-02 16:02:35 +0800141FaceUpdateCommand::FaceUpdateCommand()
142 : ControlCommand("faces", "update")
143{
144 m_requestValidator
Eric Newberryda916d62016-08-11 23:04:34 -0700145 .optional(CONTROL_PARAMETER_FACE_ID)
146 .optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
147 .optional(CONTROL_PARAMETER_FLAGS)
148 .optional(CONTROL_PARAMETER_MASK);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800149 m_responseValidator
Eric Newberry138ef2c2016-08-15 20:29:03 -0700150 .required(CONTROL_PARAMETER_FACE_ID)
151 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
152 .required(CONTROL_PARAMETER_FLAGS);
Eric Newberryda916d62016-08-11 23:04:34 -0700153}
154
155void
156FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
157{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700158 if (!parameters.hasFaceId()) {
159 parameters.setFaceId(0);
160 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800161}
162
163void
164FaceUpdateCommand::validateRequest(const ControlParameters& parameters) const
165{
166 this->ControlCommand::validateRequest(parameters);
167
Eric Newberryda916d62016-08-11 23:04:34 -0700168 if (parameters.hasFlags() != parameters.hasMask()) {
169 BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
Yanbiao Licbdacb22016-08-02 16:02:35 +0800170 }
171}
172
173void
174FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
175{
Eric Newberry138ef2c2016-08-15 20:29:03 -0700176 this->ControlCommand::validateResponse(parameters);
177
178 if (parameters.getFaceId() == 0) {
179 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
180 }
Yanbiao Licbdacb22016-08-02 16:02:35 +0800181}
182
Junxiao Shi70911652014-08-12 10:14:24 -0700183FaceDestroyCommand::FaceDestroyCommand()
184 : ControlCommand("faces", "destroy")
185{
186 m_requestValidator
187 .required(CONTROL_PARAMETER_FACE_ID);
188 m_responseValidator = m_requestValidator;
189}
190
191void
192FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
193{
194 this->ControlCommand::validateRequest(parameters);
195
196 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700197 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700198 }
199}
200
201void
202FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
203{
204 this->validateRequest(parameters);
205}
206
207FaceLocalControlCommand::FaceLocalControlCommand(const std::string& verb)
208 : ControlCommand("faces", verb)
209{
210 m_requestValidator
211 .required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
212 m_responseValidator = m_requestValidator;
213}
214
215void
216FaceLocalControlCommand::validateRequest(const ControlParameters& parameters) const
217{
218 this->ControlCommand::validateRequest(parameters);
219
220 switch (parameters.getLocalControlFeature()) {
221 case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
222 case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
223 break;
224 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700225 BOOST_THROW_EXCEPTION(ArgumentError("LocalControlFeature is invalid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700226 }
227}
228
229void
230FaceLocalControlCommand::validateResponse(const ControlParameters& parameters) const
231{
232 this->validateRequest(parameters);
233}
234
235FaceEnableLocalControlCommand::FaceEnableLocalControlCommand()
236 : FaceLocalControlCommand("enable-local-control")
237{
238}
239
240FaceDisableLocalControlCommand::FaceDisableLocalControlCommand()
241 : FaceLocalControlCommand("disable-local-control")
242{
243}
244
245FibAddNextHopCommand::FibAddNextHopCommand()
246 : ControlCommand("fib", "add-nexthop")
247{
248 m_requestValidator
249 .required(CONTROL_PARAMETER_NAME)
250 .optional(CONTROL_PARAMETER_FACE_ID)
251 .optional(CONTROL_PARAMETER_COST);
252 m_responseValidator
253 .required(CONTROL_PARAMETER_NAME)
254 .required(CONTROL_PARAMETER_FACE_ID)
255 .required(CONTROL_PARAMETER_COST);
256}
257
258void
259FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
260{
261 if (!parameters.hasFaceId()) {
262 parameters.setFaceId(0);
263 }
264 if (!parameters.hasCost()) {
265 parameters.setCost(0);
266 }
267}
268
269void
270FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
271{
272 this->ControlCommand::validateResponse(parameters);
273
274 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700275 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700276 }
277}
278
279FibRemoveNextHopCommand::FibRemoveNextHopCommand()
280 : ControlCommand("fib", "remove-nexthop")
281{
282 m_requestValidator
283 .required(CONTROL_PARAMETER_NAME)
284 .optional(CONTROL_PARAMETER_FACE_ID);
285 m_responseValidator
286 .required(CONTROL_PARAMETER_NAME)
287 .required(CONTROL_PARAMETER_FACE_ID);
288}
289
290void
291FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
292{
293 if (!parameters.hasFaceId()) {
294 parameters.setFaceId(0);
295 }
296}
297
298void
299FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
300{
301 this->ControlCommand::validateResponse(parameters);
302
303 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700304 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700305 }
306}
307
308StrategyChoiceSetCommand::StrategyChoiceSetCommand()
309 : ControlCommand("strategy-choice", "set")
310{
311 m_requestValidator
312 .required(CONTROL_PARAMETER_NAME)
313 .required(CONTROL_PARAMETER_STRATEGY);
314 m_responseValidator = m_requestValidator;
315}
316
317StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
318 : ControlCommand("strategy-choice", "unset")
319{
320 m_requestValidator
321 .required(CONTROL_PARAMETER_NAME);
322 m_responseValidator = m_requestValidator;
323}
324
325void
326StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
327{
328 this->ControlCommand::validateRequest(parameters);
329
330 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700331 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700332 }
333}
334
335void
336StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
337{
338 this->validateRequest(parameters);
339}
340
341RibRegisterCommand::RibRegisterCommand()
342 : ControlCommand("rib", "register")
343{
344 m_requestValidator
345 .required(CONTROL_PARAMETER_NAME)
346 .optional(CONTROL_PARAMETER_FACE_ID)
347 .optional(CONTROL_PARAMETER_ORIGIN)
348 .optional(CONTROL_PARAMETER_COST)
349 .optional(CONTROL_PARAMETER_FLAGS)
350 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
351 m_responseValidator
352 .required(CONTROL_PARAMETER_NAME)
353 .required(CONTROL_PARAMETER_FACE_ID)
354 .required(CONTROL_PARAMETER_ORIGIN)
355 .required(CONTROL_PARAMETER_COST)
356 .required(CONTROL_PARAMETER_FLAGS)
357 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
358}
359
360void
361RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
362{
363 if (!parameters.hasFaceId()) {
364 parameters.setFaceId(0);
365 }
366 if (!parameters.hasOrigin()) {
367 parameters.setOrigin(ROUTE_ORIGIN_APP);
368 }
369 if (!parameters.hasCost()) {
370 parameters.setCost(0);
371 }
372 if (!parameters.hasFlags()) {
373 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
374 }
375}
376
377void
378RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
379{
380 this->ControlCommand::validateResponse(parameters);
381
382 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700383 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700384 }
385}
386
387RibUnregisterCommand::RibUnregisterCommand()
388 : ControlCommand("rib", "unregister")
389{
390 m_requestValidator
391 .required(CONTROL_PARAMETER_NAME)
392 .optional(CONTROL_PARAMETER_FACE_ID)
393 .optional(CONTROL_PARAMETER_ORIGIN);
394 m_responseValidator
395 .required(CONTROL_PARAMETER_NAME)
396 .required(CONTROL_PARAMETER_FACE_ID)
397 .required(CONTROL_PARAMETER_ORIGIN);
398}
399
400void
401RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
402{
403 if (!parameters.hasFaceId()) {
404 parameters.setFaceId(0);
405 }
406 if (!parameters.hasOrigin()) {
407 parameters.setOrigin(ROUTE_ORIGIN_APP);
408 }
409}
410
411void
412RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
413{
414 this->ControlCommand::validateResponse(parameters);
415
416 if (parameters.getFaceId() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700417 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must not be zero"));
Junxiao Shi70911652014-08-12 10:14:24 -0700418 }
419}
420
421} // namespace nfd
422} // namespace ndn