blob: 5ecf9751579b96a8eee518e4114f3fc962ab3363 [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"
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 }
91}
92
93FaceCreateCommand::FaceCreateCommand()
94 : ControlCommand("faces", "create")
95{
96 m_requestValidator
Yukai Tud93c5fc2015-08-25 11:37:16 +080097 .required(CONTROL_PARAMETER_URI)
Teng Liangf4908b12017-03-29 15:24:03 -070098 .optional(CONTROL_PARAMETER_LOCAL_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)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000104 .required(CONTROL_PARAMETER_URI)
105 .required(CONTROL_PARAMETER_LOCAL_URI)
Eric Newberryda916d62016-08-11 23:04:34 -0700106 .required(CONTROL_PARAMETER_FACE_PERSISTENCY)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000107 .required(CONTROL_PARAMETER_FLAGS);
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
Junxiao Shi70911652014-08-12 10:14:24 -0700204FibAddNextHopCommand::FibAddNextHopCommand()
205 : ControlCommand("fib", "add-nexthop")
206{
207 m_requestValidator
208 .required(CONTROL_PARAMETER_NAME)
209 .optional(CONTROL_PARAMETER_FACE_ID)
210 .optional(CONTROL_PARAMETER_COST);
211 m_responseValidator
212 .required(CONTROL_PARAMETER_NAME)
213 .required(CONTROL_PARAMETER_FACE_ID)
214 .required(CONTROL_PARAMETER_COST);
215}
216
217void
218FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
219{
220 if (!parameters.hasFaceId()) {
221 parameters.setFaceId(0);
222 }
223 if (!parameters.hasCost()) {
224 parameters.setCost(0);
225 }
226}
227
228void
229FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
230{
231 this->ControlCommand::validateResponse(parameters);
232
Davide Pesaventof8503d22017-02-17 01:19:10 -0500233 if (parameters.getFaceId() == INVALID_FACE_ID) {
234 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700235 }
236}
237
238FibRemoveNextHopCommand::FibRemoveNextHopCommand()
239 : ControlCommand("fib", "remove-nexthop")
240{
241 m_requestValidator
242 .required(CONTROL_PARAMETER_NAME)
243 .optional(CONTROL_PARAMETER_FACE_ID);
244 m_responseValidator
245 .required(CONTROL_PARAMETER_NAME)
246 .required(CONTROL_PARAMETER_FACE_ID);
247}
248
249void
250FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
251{
252 if (!parameters.hasFaceId()) {
253 parameters.setFaceId(0);
254 }
255}
256
257void
258FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
259{
260 this->ControlCommand::validateResponse(parameters);
261
Davide Pesaventof8503d22017-02-17 01:19:10 -0500262 if (parameters.getFaceId() == INVALID_FACE_ID) {
263 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700264 }
265}
266
267StrategyChoiceSetCommand::StrategyChoiceSetCommand()
268 : ControlCommand("strategy-choice", "set")
269{
270 m_requestValidator
271 .required(CONTROL_PARAMETER_NAME)
272 .required(CONTROL_PARAMETER_STRATEGY);
273 m_responseValidator = m_requestValidator;
274}
275
276StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
277 : ControlCommand("strategy-choice", "unset")
278{
279 m_requestValidator
280 .required(CONTROL_PARAMETER_NAME);
281 m_responseValidator = m_requestValidator;
282}
283
284void
285StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
286{
287 this->ControlCommand::validateRequest(parameters);
288
289 if (parameters.getName().size() == 0) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700290 BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
Junxiao Shi70911652014-08-12 10:14:24 -0700291 }
292}
293
294void
295StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
296{
297 this->validateRequest(parameters);
298}
299
300RibRegisterCommand::RibRegisterCommand()
301 : ControlCommand("rib", "register")
302{
303 m_requestValidator
304 .required(CONTROL_PARAMETER_NAME)
305 .optional(CONTROL_PARAMETER_FACE_ID)
306 .optional(CONTROL_PARAMETER_ORIGIN)
307 .optional(CONTROL_PARAMETER_COST)
308 .optional(CONTROL_PARAMETER_FLAGS)
309 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
310 m_responseValidator
311 .required(CONTROL_PARAMETER_NAME)
312 .required(CONTROL_PARAMETER_FACE_ID)
313 .required(CONTROL_PARAMETER_ORIGIN)
314 .required(CONTROL_PARAMETER_COST)
315 .required(CONTROL_PARAMETER_FLAGS)
316 .optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
317}
318
319void
320RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
321{
322 if (!parameters.hasFaceId()) {
323 parameters.setFaceId(0);
324 }
325 if (!parameters.hasOrigin()) {
326 parameters.setOrigin(ROUTE_ORIGIN_APP);
327 }
328 if (!parameters.hasCost()) {
329 parameters.setCost(0);
330 }
331 if (!parameters.hasFlags()) {
332 parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
333 }
334}
335
336void
337RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
338{
339 this->ControlCommand::validateResponse(parameters);
340
Davide Pesaventof8503d22017-02-17 01:19:10 -0500341 if (parameters.getFaceId() == INVALID_FACE_ID) {
342 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700343 }
344}
345
346RibUnregisterCommand::RibUnregisterCommand()
347 : ControlCommand("rib", "unregister")
348{
349 m_requestValidator
350 .required(CONTROL_PARAMETER_NAME)
351 .optional(CONTROL_PARAMETER_FACE_ID)
352 .optional(CONTROL_PARAMETER_ORIGIN);
353 m_responseValidator
354 .required(CONTROL_PARAMETER_NAME)
355 .required(CONTROL_PARAMETER_FACE_ID)
356 .required(CONTROL_PARAMETER_ORIGIN);
357}
358
359void
360RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
361{
362 if (!parameters.hasFaceId()) {
363 parameters.setFaceId(0);
364 }
365 if (!parameters.hasOrigin()) {
366 parameters.setOrigin(ROUTE_ORIGIN_APP);
367 }
368}
369
370void
371RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
372{
373 this->ControlCommand::validateResponse(parameters);
374
Davide Pesaventof8503d22017-02-17 01:19:10 -0500375 if (parameters.getFaceId() == INVALID_FACE_ID) {
376 BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
Junxiao Shi70911652014-08-12 10:14:24 -0700377 }
378}
379
380} // namespace nfd
381} // namespace ndn