@@ -87,11 +87,12 @@ makeAcceptAllAuthorization();
87
87
88
88
// ---- CONTROL COMMAND ----
89
89
90
- /* * \brief A function to validate input ControlParameters.
91
- * \param params parsed ControlParameters;
92
- * This is guaranteed to have correct type for the command.
90
+ /* *
91
+ * \brief A function to validate and normalize the incoming request parameters.
92
+ * \param params The parsed ControlParameters; guaranteed to be of the correct (sub-)type
93
+ * for the command.
93
94
*/
94
- using ValidateParameters = std::function<bool (const ControlParameters& params)>;
95
+ using ValidateParameters = std::function<bool (ControlParameters& params)>;
95
96
96
97
/* *
97
98
* \brief A function to be called after a ControlCommandHandler completes.
@@ -183,7 +184,7 @@ class Dispatcher : noncopyable
183
184
184
185
public: // ControlCommand
185
186
/* *
186
- * \brief Register a ControlCommand.
187
+ * \brief Register a ControlCommand (old style) .
187
188
* \tparam ParametersType Concrete subclass of ControlParameters used by this command.
188
189
* \param relPrefix The name prefix for this command relative to the top-level prefix,
189
190
* e.g., "faces/create". The prefixes across all ControlCommands,
@@ -219,17 +220,69 @@ class Dispatcher : noncopyable
219
220
{
220
221
checkPrefix (relPrefix);
221
222
222
- ControlParametersParser parse = [] (const name::Component& comp) -> shared_ptr<ControlParameters> {
223
+ auto relPrefixLen = relPrefix.size ();
224
+ ParametersParser parse = [relPrefixLen] (const Name& prefix,
225
+ const auto & interest) -> shared_ptr<ControlParameters> {
226
+ const name::Component& comp = interest.getName ().get (prefix.size () + relPrefixLen);
223
227
return make_shared<ParametersType>(comp.blockFromValue ());
224
228
};
225
229
226
- m_handlers[relPrefix] = [this , relPrefix,
227
- parse = std::move (parse),
228
- authorize = std::move (authorize),
229
- validate = std::move (validate),
230
- handle = std::move (handle)] (const auto & prefix, const auto & interest) {
231
- processCommand (prefix, relPrefix, interest, parse, authorize,
232
- std::move (validate), std::move (handle));
230
+ m_handlers[relPrefix] = [this ,
231
+ parser = std::move (parse),
232
+ authorizer = std::move (authorize),
233
+ validator = std::move (validate),
234
+ handler = std::move (handle)] (const auto & prefix, const auto & interest) {
235
+ processCommand (prefix, interest, parser, authorizer, std::move (validator), std::move (handler));
236
+ };
237
+ }
238
+
239
+ /* *
240
+ * \brief Register a ControlCommand (new style).
241
+ * \tparam Command The type of ControlCommand to register.
242
+ * \param authorize Callback to authorize the incoming commands.
243
+ * \param handle Callback to handle the commands.
244
+ * \pre No top-level prefix has been added.
245
+ * \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix.
246
+ * \throw std::domain_error One or more top-level prefixes have been added.
247
+ *
248
+ * Procedure for processing a ControlCommand registered through this function:
249
+ * 1. Extract the parameters from the request by invoking `Command::parseRequest` on the
250
+ * incoming Interest; if parsing fails, abort these steps.
251
+ * 2. Perform authorization; if the authorization is rejected, perform the RejectReply action
252
+ * and abort these steps.
253
+ * 3. Validate the parameters with `Command::validateRequest`.
254
+ * 4. Normalize the parameters with `Command::applyDefaultsToRequest`.
255
+ * 5. If either step 3 or 4 fails, create a ControlResponse with StatusCode 400 and go to step 7.
256
+ * 6. Invoke the command handler, wait until CommandContinuation is called.
257
+ * 7. Encode the ControlResponse into one Data packet.
258
+ * 8. Sign the Data packet.
259
+ * 9. If the Data packet is too large, log an error and abort these steps.
260
+ * 10. Send the signed Data packet.
261
+ */
262
+ template <typename Command>
263
+ void
264
+ addControlCommand (Authorization authorize, ControlCommandHandler handle)
265
+ {
266
+ auto relPrefix = Command::getName ();
267
+ checkPrefix (relPrefix);
268
+
269
+ ParametersParser parse = [] (const Name& prefix, const auto & interest) {
270
+ return Command::parseRequest (interest, prefix.size ());
271
+ };
272
+ ValidateParameters validate = [] (auto & params) {
273
+ auto & reqParams = static_cast <typename Command::RequestParameters&>(params);
274
+ Command::validateRequest (reqParams);
275
+ Command::applyDefaultsToRequest (reqParams);
276
+ // for compatibility with ValidateParameters signature; consider refactoring in the future
277
+ return true ;
278
+ };
279
+
280
+ m_handlers[relPrefix] = [this ,
281
+ parser = std::move (parse),
282
+ authorizer = std::move (authorize),
283
+ validator = std::move (validate),
284
+ handler = std::move (handle)] (const auto & prefix, const auto & interest) {
285
+ processCommand (prefix, interest, parser, authorizer, std::move (validator), std::move (handler));
233
286
};
234
287
}
235
288
@@ -299,11 +352,11 @@ class Dispatcher : noncopyable
299
352
using InterestHandler = std::function<void (const Name& prefix, const Interest&)>;
300
353
301
354
/* *
302
- * @brief The parser for extracting control parameters from a name component .
355
+ * @brief The parser for extracting the parameters from a command request .
303
356
* @return A shared pointer to the extracted ControlParameters.
304
- * @throw tlv::Error if the name component cannot be parsed as ControlParameters
357
+ * @throw tlv::Error The request parameters cannot be parsed.
305
358
*/
306
- using ControlParametersParser = std::function<shared_ptr<ControlParameters>(const name::Component &)>;
359
+ using ParametersParser = std::function<shared_ptr<ControlParameters>(const Name& prefix, const Interest &)>;
307
360
308
361
void
309
362
checkPrefix (const PartialName& relPrefix) const ;
@@ -364,7 +417,6 @@ class Dispatcher : noncopyable
364
417
* @brief Process an incoming control command Interest before authorization.
365
418
*
366
419
* @param prefix the top-level prefix
367
- * @param relPrefix the relative prefix
368
420
* @param interest the incoming Interest
369
421
* @param parse function to extract the control parameters from the command
370
422
* @param authorize function to determine whether the command is authorized
@@ -373,9 +425,8 @@ class Dispatcher : noncopyable
373
425
*/
374
426
void
375
427
processCommand (const Name& prefix,
376
- const Name& relPrefix,
377
428
const Interest& interest,
378
- const ControlParametersParser & parse,
429
+ const ParametersParser & parse,
379
430
const Authorization& authorize,
380
431
ValidateParameters validate,
381
432
ControlCommandHandler handler);
0 commit comments