method to return smart pointer.
namespace isc {
namespace d2 {
+class D2CfgContext;
+/// @brief Pointer to a configuration context.
+typedef boost::shared_ptr<D2CfgContext> D2CfgContextPtr;
+
/// @brief DHCP-DDNS Configuration Context
///
/// Implements the storage container for configuration context.
/// @brief Creates a clone of this context object.
///
- /// @return returns a raw pointer to the new clone.
- virtual D2CfgContext* clone() {
- return (new D2CfgContext(*this));
+ /// @return returns a pointer to the new clone.
+ virtual DCfgContextBasePtr clone() {
+ return (DCfgContextBasePtr(new D2CfgContext(*this)));
}
/// @brief Fetches the forward DNS domain list manager.
typedef boost::shared_ptr<DdnsDomainListMgr> DdnsDomainListMgrPtr;
-/// @brief Pointer to a configuration context.
-typedef boost::shared_ptr<D2CfgContext> D2CfgContextPtr;
/// @brief DHCP-DDNS Configuration Manager
///
/// @brief Creates a clone of a DStubContext.
///
- /// @return returns a raw pointer to the new clone.
- virtual DScalarContext* clone() {
- return (new DScalarContext(*this));
+ /// @return returns a pointer to the new clone.
+ virtual DCfgContextBasePtr clone() {
+ return (DCfgContextBasePtr(new DScalarContext(*this)));
}
protected:
DScalarContext& operator=(const DScalarContext& rhs);
};
+/// @brief Defines a pointer for DScalarContext instances.
+typedef boost::shared_ptr<DScalarContext> DScalarContextPtr;
+
/// @brief Parser for TSIGKeyInfo
///
/// This class parses the configuration element "tsig_key" defined in
// inconsistency if the parsing operation fails after the context has been
// modified. We need to preserve the original context here
// so as we can rollback changes when an error occurs.
- DCfgContextBasePtr original_context(context_->clone());
+ DCfgContextBasePtr original_context = context_->clone();
// Answer will hold the result returned to the caller.
ConstElementPtr answer;
if (parse_order_.size() > 0) {
// For each element_id in the parse order list, look for it in the
// value map. If the element exists in the map, pass it and it's
- // associated data in for parsing.
- // If there is no matching entry in the value map an error is
- // thrown. Optional elements may not be used with ordered parsing.
+ // associated data in for parsing.
+ // If there is no matching entry in the value map an error is
+ // thrown. Note, that elements tagged as "optional" from the user
+ // perspective must still have default or empty entries in the
+ // configuration set to be parsed.
int parsed_count = 0;
std::map<std::string, ConstElementPtr>::const_iterator it;
BOOST_FOREACH(element_id, parse_order_) {
else {
LOG_ERROR(dctl_logger, DCTL_ORDER_NO_ELEMENT)
.arg(element_id);
- isc_throw(DCfgMgrBaseError, "Element:" << element_id <<
+ isc_throw(DCfgMgrBaseError, "Element:" << element_id <<
" is listed in the parse order but is not "
" present in the configuration");
}
// Better to hold the engineer accountable. So, if we parsed none
// or we parsed fewer than are in the map; then either the parse i
// order is incomplete OR the map has unsupported values.
- if (!parsed_count ||
+ if (!parsed_count ||
(parsed_count && ((parsed_count + 1) < values_map.size()))) {
LOG_ERROR(dctl_logger, DCTL_ORDER_ERROR);
- isc_throw(DCfgMgrBaseError,
+ isc_throw(DCfgMgrBaseError,
"Configuration contains elements not in parse order");
}
} else {
// nothing something we are concerned with here.)
parser->commit();
} catch (const isc::Exception& ex) {
- isc_throw(DCfgMgrBaseError,
+ isc_throw(DCfgMgrBaseError,
"Could not build and commit: " << ex.what());
} catch (...) {
isc_throw(DCfgMgrBaseError, "Non-ISC exception occurred");
isc::Exception(file, line, what) { };
};
+class DCfgContextBase;
+/// @brief Pointer to a configuration context.
+typedef boost::shared_ptr<DCfgContextBase> DCfgContextBasePtr;
+
/// @brief Abstract class that implements a container for configuration context.
/// It provides a single enclosure for the storage of configuration parameters
/// and any other context specific information that needs to be accessible
/// public:
/// :
/// // Clone calls its own copy constructor
- /// virtual DStubContext* clone() {
- /// return (new DStubContext(*this));
+ /// virtual DCfgContextBasePtr clone() {
+ /// return (DCfgContextBasePtr(new DStubContext(*this)));
/// }
///
/// // Note that the copy constructor calls the base class copy ctor
/// :
/// @endcode
///
- /// @return returns a raw pointer to the new clone.
- virtual DCfgContextBase* clone() = 0;
+ /// @return returns a pointer to the new clone.
+ virtual DCfgContextBasePtr clone() = 0;
protected:
/// @brief Copy constructor for use by derivations in clone().
isc::dhcp::StringStoragePtr string_values_;
};
-/// @brief Pointer to a configuration context.
-typedef boost::shared_ptr<DCfgContextBase> DCfgContextBasePtr;
-
/// @brief Defines an unsorted, list of string Element IDs.
typedef std::vector<std::string> ElementIdList;
{
"item_name": "forward_ddns",
"item_type": "map",
- "item_optional": false,
+ "item_optional": true,
"item_default": {},
"map_item_spec": [
{
{
"item_name": "reverse_ddns",
"item_type": "map",
- "item_optional": false,
+ "item_optional": true,
"item_default": {},
"map_item_spec": [
{
return (extra_values_);
}
-DStubContext*
+DCfgContextBasePtr
DStubContext::clone() {
- return (new DStubContext(*this));
+ return (DCfgContextBasePtr(new DStubContext(*this)));
}
DStubContext::DStubContext(const DStubContext& rhs): DCfgContextBase(rhs),
/// @brief Creates a clone of a DStubContext.
///
- /// @return returns a raw pointer to the new clone.
- virtual DStubContext* clone();
+ /// @return returns a pointer to the new clone.
+ virtual DCfgContextBasePtr clone();
protected:
/// @brief Copy constructor
try {
config_set_ = isc::data::Element::fromJSON(json_text);
} catch (...) {
- // This is so we can diagnose parsing mistakes during test
- // development.
- std::cerr << "fromJSON failed to parse text" << json_text
+ #if 0
+ // Handy for diagnostics
+ std::cout << "fromJSON failed to parse text" << json_text
<< std::endl;
+ #endif
return (false);
}
int rcode = 0;
isc::data::ConstElementPtr comment;
comment = isc::config::parseAnswer(rcode, answer_);
+ #if 0
// Handy for diagnostics
- #if 1
if (rcode != 0) {
std::cout << "checkAnswer rcode:" << rcode << " comment: "
<< *comment << std::endl;