blob: a51ecb6b4e88d0ab6fdb9dd24dc5ba7b74198e5e [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "control-command.hpp"
#include "command-options.hpp" // only used in deprecated functions
namespace ndn {
namespace nfd {
ControlCommand::ControlCommand(const std::string& module, const std::string& verb)
: m_module(module)
, m_verb(verb)
{
}
ControlCommand::~ControlCommand() = default;
void
ControlCommand::validateRequest(const ControlParameters& parameters) const
{
m_requestValidator.validate(parameters);
}
void
ControlCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
}
void
ControlCommand::validateResponse(const ControlParameters& parameters) const
{
m_responseValidator.validate(parameters);
}
void
ControlCommand::applyDefaultsToResponse(ControlParameters& parameters) const
{
}
Name
ControlCommand::getRequestName(const Name& commandPrefix,
const ControlParameters& parameters) const
{
this->validateRequest(parameters);
Name name = commandPrefix;
name.append(m_module).append(m_verb);
name.append(parameters.wireEncode());
return name;
}
ControlCommand::FieldValidator::FieldValidator()
: m_required(CONTROL_PARAMETER_UBOUND)
, m_optional(CONTROL_PARAMETER_UBOUND)
{
}
void
ControlCommand::FieldValidator::validate(const ControlParameters& parameters) const
{
const std::vector<bool>& presentFields = parameters.getPresentFields();
for (size_t i = 0; i < CONTROL_PARAMETER_UBOUND; ++i) {
bool isPresent = presentFields[i];
if (m_required[i]) {
if (!isPresent) {
BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
}
}
else if (isPresent && !m_optional[i]) {
BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
}
}
}
FaceCreateCommand::FaceCreateCommand()
: ControlCommand("faces", "create")
{
m_requestValidator
.required(CONTROL_PARAMETER_URI)
.optional(CONTROL_PARAMETER_LOCAL_URI)
.optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
.optional(CONTROL_PARAMETER_FLAGS)
.optional(CONTROL_PARAMETER_MASK);
m_responseValidator
.required(CONTROL_PARAMETER_FACE_ID)
.required(CONTROL_PARAMETER_FACE_PERSISTENCY)
.optional(CONTROL_PARAMETER_FLAGS)
.optional(CONTROL_PARAMETER_URI);
}
void
FaceCreateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFacePersistency()) {
parameters.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
}
}
void
FaceCreateCommand::validateRequest(const ControlParameters& parameters) const
{
this->ControlCommand::validateRequest(parameters);
if (parameters.hasFlags() != parameters.hasMask()) {
BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
}
}
void
FaceCreateCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
FaceUpdateCommand::FaceUpdateCommand()
: ControlCommand("faces", "update")
{
m_requestValidator
.optional(CONTROL_PARAMETER_FACE_ID)
.optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
.optional(CONTROL_PARAMETER_FLAGS)
.optional(CONTROL_PARAMETER_MASK);
m_responseValidator
.required(CONTROL_PARAMETER_FACE_ID)
.required(CONTROL_PARAMETER_FACE_PERSISTENCY)
.required(CONTROL_PARAMETER_FLAGS);
}
void
FaceUpdateCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFaceId()) {
parameters.setFaceId(0);
}
}
void
FaceUpdateCommand::validateRequest(const ControlParameters& parameters) const
{
this->ControlCommand::validateRequest(parameters);
if (parameters.hasFlags() != parameters.hasMask()) {
BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
}
}
void
FaceUpdateCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
FaceDestroyCommand::FaceDestroyCommand()
: ControlCommand("faces", "destroy")
{
m_requestValidator
.required(CONTROL_PARAMETER_FACE_ID);
m_responseValidator = m_requestValidator;
}
void
FaceDestroyCommand::validateRequest(const ControlParameters& parameters) const
{
this->ControlCommand::validateRequest(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
void
FaceDestroyCommand::validateResponse(const ControlParameters& parameters) const
{
this->validateRequest(parameters);
}
FaceLocalControlCommand::FaceLocalControlCommand(const std::string& verb)
: ControlCommand("faces", verb)
{
m_requestValidator
.required(CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE);
m_responseValidator = m_requestValidator;
}
void
FaceLocalControlCommand::validateRequest(const ControlParameters& parameters) const
{
this->ControlCommand::validateRequest(parameters);
switch (parameters.getLocalControlFeature()) {
case LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID:
case LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID:
break;
default:
BOOST_THROW_EXCEPTION(ArgumentError("LocalControlFeature is invalid"));
}
}
void
FaceLocalControlCommand::validateResponse(const ControlParameters& parameters) const
{
this->validateRequest(parameters);
}
FaceEnableLocalControlCommand::FaceEnableLocalControlCommand()
: FaceLocalControlCommand("enable-local-control")
{
}
FaceDisableLocalControlCommand::FaceDisableLocalControlCommand()
: FaceLocalControlCommand("disable-local-control")
{
}
FibAddNextHopCommand::FibAddNextHopCommand()
: ControlCommand("fib", "add-nexthop")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME)
.optional(CONTROL_PARAMETER_FACE_ID)
.optional(CONTROL_PARAMETER_COST);
m_responseValidator
.required(CONTROL_PARAMETER_NAME)
.required(CONTROL_PARAMETER_FACE_ID)
.required(CONTROL_PARAMETER_COST);
}
void
FibAddNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFaceId()) {
parameters.setFaceId(0);
}
if (!parameters.hasCost()) {
parameters.setCost(0);
}
}
void
FibAddNextHopCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
FibRemoveNextHopCommand::FibRemoveNextHopCommand()
: ControlCommand("fib", "remove-nexthop")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME)
.optional(CONTROL_PARAMETER_FACE_ID);
m_responseValidator
.required(CONTROL_PARAMETER_NAME)
.required(CONTROL_PARAMETER_FACE_ID);
}
void
FibRemoveNextHopCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFaceId()) {
parameters.setFaceId(0);
}
}
void
FibRemoveNextHopCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
StrategyChoiceSetCommand::StrategyChoiceSetCommand()
: ControlCommand("strategy-choice", "set")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME)
.required(CONTROL_PARAMETER_STRATEGY);
m_responseValidator = m_requestValidator;
}
StrategyChoiceUnsetCommand::StrategyChoiceUnsetCommand()
: ControlCommand("strategy-choice", "unset")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME);
m_responseValidator = m_requestValidator;
}
void
StrategyChoiceUnsetCommand::validateRequest(const ControlParameters& parameters) const
{
this->ControlCommand::validateRequest(parameters);
if (parameters.getName().size() == 0) {
BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
}
}
void
StrategyChoiceUnsetCommand::validateResponse(const ControlParameters& parameters) const
{
this->validateRequest(parameters);
}
RibRegisterCommand::RibRegisterCommand()
: ControlCommand("rib", "register")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME)
.optional(CONTROL_PARAMETER_FACE_ID)
.optional(CONTROL_PARAMETER_ORIGIN)
.optional(CONTROL_PARAMETER_COST)
.optional(CONTROL_PARAMETER_FLAGS)
.optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
m_responseValidator
.required(CONTROL_PARAMETER_NAME)
.required(CONTROL_PARAMETER_FACE_ID)
.required(CONTROL_PARAMETER_ORIGIN)
.required(CONTROL_PARAMETER_COST)
.required(CONTROL_PARAMETER_FLAGS)
.optional(CONTROL_PARAMETER_EXPIRATION_PERIOD);
}
void
RibRegisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFaceId()) {
parameters.setFaceId(0);
}
if (!parameters.hasOrigin()) {
parameters.setOrigin(ROUTE_ORIGIN_APP);
}
if (!parameters.hasCost()) {
parameters.setCost(0);
}
if (!parameters.hasFlags()) {
parameters.setFlags(ROUTE_FLAG_CHILD_INHERIT);
}
}
void
RibRegisterCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
RibUnregisterCommand::RibUnregisterCommand()
: ControlCommand("rib", "unregister")
{
m_requestValidator
.required(CONTROL_PARAMETER_NAME)
.optional(CONTROL_PARAMETER_FACE_ID)
.optional(CONTROL_PARAMETER_ORIGIN);
m_responseValidator
.required(CONTROL_PARAMETER_NAME)
.required(CONTROL_PARAMETER_FACE_ID)
.required(CONTROL_PARAMETER_ORIGIN);
}
void
RibUnregisterCommand::applyDefaultsToRequest(ControlParameters& parameters) const
{
if (!parameters.hasFaceId()) {
parameters.setFaceId(0);
}
if (!parameters.hasOrigin()) {
parameters.setOrigin(ROUTE_ORIGIN_APP);
}
}
void
RibUnregisterCommand::validateResponse(const ControlParameters& parameters) const
{
this->ControlCommand::validateResponse(parameters);
if (parameters.getFaceId() == INVALID_FACE_ID) {
BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
}
}
} // namespace nfd
} // namespace ndn