Commit 7be263c7 authored by Thomas Markwalder's avatar Thomas Markwalder

[master] Merge branch 'trac3158'

Adds D2 developer's guide
parents d1c178b9 5c57d33f
......@@ -769,7 +769,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = ../doc/images ../src/lib/hooks/images
IMAGE_PATH = ../doc/images ../src/lib/hooks/images ../src/bin/d2/images
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
......
......@@ -64,6 +64,16 @@
* - @subpage dhcpv6OptionsParse
* - @subpage dhcpv6Classifier
* - @subpage dhcpv6Other
* - @subpage d2
* - @subpage d2CPL
* - @subpage d2ProcesDerivation
* - @subpage d2ConfigMgt
* - @subpage d2NCRReceipt
* - @subpage d2DDNSUpdateExecution
* - @subpage d2EventLoop
* - @subpage d2TransDetail
* - @subpage d2StateModel
* - @subpage d2TransExecExample
* - @subpage libdhcp
* - @subpage libdhcpIntro
* - @subpage libdhcpRelay
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
/**
@page d2 DHCP-DDNS Component
Kea is capable of sending dynamic DNS updates to DNS Servers, based on lease
changes made by Kea's DHCP servers. When DDNS updating is enabled,
the DHCP servers generate requests to update DNS as they make lease changes.
These requests, implemented by isc::dhcp_ddns::NameChangeRequest (NCR), are sent
to a separate process, informally known as D2. D2 processes these requests by
carrying out DDNS conversations with the appropriate DNS servers such that they
update the DNS data.
The design documentation for D2 can be found here:
<a href="http://kea.isc.org/wiki/DhcpDdnsDesign">D2 Design</a>.
This document contains several UML diagrams, and a few conventions used within
these diagrams are worth noting:
- If a class is appearing on class diagram for the first time (within this
document) its background color will be yellow. If it has been presented
already, its background color will be blue and/or its details may not be shown.
- Associations between classes in D2 are implemented in most cases via typedefs,
sometimes through a small chain of typedefs. These typedefs are shown for
accuracy but are unimportant to a general discussion.
@section d2CPL Controllable Process Layer (CPL)
D2 is built upon an abstract set of classes referred to as the Controllable
Process Layer or CPL. This layer provides the essentials for a controllable,
configurable, asynchronous process. They are the result of an effort to
distill the common facets of process control currently duplicated in Kea's
DHCP servers into a reusable construct. The classes which form this abstract
base are shown in the following class diagram:
@image html abstract_app_classes.svg "Controllable Process Layer Classes"
- isc::d2::DControllerBase - provides all of the services necessary to manage
an application process class derived from isc::d2::DProcess. These services include:
- Command line argument handling
- Process instantiation and initialization
- Support for stand-alone execution
- Support for integrated operation as a BIND10 module (session management
and event handling)
- Process event loop invocation and shutdown
.
It creates and manages an instance of isc::d2::DProcessBase. The CPL is designed
for asynchronous event processing applications. It is constructed to use ASIO
library for IO processing. DControllerBase own an isc::asiolink::io_service instance and it pas ses this into the @c DProcessBase constructor and it is this
service that is used drivel the process's event loop.
@c DControllerBase also provides the ability to operate one of two modes:
"stand-alone" mode or "managed" mode. In stand-alone mode, the controller has
no IO of it's own, thus there is two-way control communication between the application and the outside world.
In "managed mode" the controller creates a BIND10 Session, allowing it to
participate as a BIND10 module and therefore receive control commands such as
configuration updates, status requests, and shutdown. BIND10 modules are
required to supply two callbacks: one for configuration events and one for
command events. @c DControllerBase supplies these callbacks which largely
pass the information through to its @c DProcessBase instance. The key aspect
to take from this is that the controller handles the interface for receiving
asynchronous commands and the invokes the appropriate services in the process's
interface.
@todo DControllerBase does yet support reading the configuration from a
command line argument. It's command line argument processing can be very easily
extended to do so.
@todo At the time of this writing Kea is being separated from the BIND10
framework. As such, use of the BIND10 Session will be removed but could
readily be replaced with an authenticated socket connection for receiving and
responding to directives asynchronously.
- isc::d2::DProcessBase - defines an asynchronous-event processor (i.e.
application) which provides a uniform interface to:
- Instantiate and initialize a process instance
- "Run" the application by starting its event loop
- Inject events to control the process
It owns an instance of @c DCfgMgrBase.
- isc::d2::DCfgMgrBase - provides the mechanisms for managing an application's
configuration. This includes services for parsing sets of configuration
values, storing the parsed information in its converted form, and retrieving
the information on demand. It owns an instance of @c DCfgContextBase, which
provides a "global" context for information that is accessible before, during,
and after parsing.
- isc::d2::DCfgContextBase - implements a container for configuration
information or "context". It provides a single enclosure for the storage of
configuration parameters or any other information that needs to accessible
within a given context.
The following sequence diagram shows how a configuration update, received
asynchronously through the session command channel, moves through the CPL:
@image html config_sequence.svg "CPL Configuration Update Sequence"
The CPL classes will likely move into a common library.
@section d2ProcesDerivation D2's CPL Derivations
D2's core application classes are DDNS-specific derivations of the CPL as show
in the diagram below:
@image html d2_app_classes.svg "D2's CPL Derivations"
- isc::d2::D2Controller - entry point for running D2, it processes command line
options, starts and controls the application process, @c D2Process.
- isc::d2::D2Process - creates and manages D2's primary resources and implements
the main event loop described in @ref d2EventLoop.
- isc::d2::D2CfgMgr - creates, updates, and provides access to D2's application
configuration which is embodied by @c D2CfgContext.
- isc::d2::D2CfgContext - warehouses D2's application configuration.
@section d2ConfigMgt Configuration Management
D2's configuration management uses the same underlying mechanisms as Kea's DHCP
servers. It's configuration information is organized into a hierarchical data
model which is mirrored in the implementation by a hierarchy of parser classes
and the runtime classes they instantiate.
D2's data model is organized as follows:
- A set of application level values such as the D2's IP address, port
- Two lists of "domains": one for Forward DNS and one for Reverse DNS. @n
Each domain is described by a zone name and a list of DNS servers that can
update that zone.
- A list of TSIG keys for conducting signed DDNS exchanges with DNS servers
The runtime classes that embody this model are shown in the following diagram:
@image html config_data_classes.svg "D2's Configuration Data Classes"
- isc::d2::D2CfgContext - D2-specific derivation of @c DCfgContextBase. It
houses the "global" configuration for an instance of D2.
- isc::d2::DdnsDomainListMgr - manages a list of domains. Currently there is
one manager instance for the list of forward domains, and one for the list of
reverse domains. In addition the domain list, it will may house other values
specific to that list of domains (e.g. enable flag)
- isc::d2::DdnsDomain - represents a DNS domain (really a zone). When requests
are received they are matched to a domain by comparing their FQDN to the domain's name.
- isc::d2::DnsServerInfo - describes a DNS server which supports DDNS for a
given domain.
- isc::d2::TSIGKeyInfo - describes a TSIG key used for authenticated DDNS for
a given domain.
The parsing classes, as one would expect, parallel the runtime classes quite
closely. The parsers are named for the runtime class they instantiate and are
either designed to parse a single occurrence of that class or list of that
class. The parser classes are shown in the diagram below:
@image html config_parser_classes.svg "D2's Configuration Parsers"
- isc::d2::DdnsDomainListMgrParser - parser for a domain list manager, it
creates a domain list parser
- isc::d2::DdnsDomainListParser - parser for a list of domains, it creates a
domain parser for domain described in a list domains
- isc::d2::DdnsDomainParser - Parser for a domain, it creates a DNS server list
parser
- isc::d2::DnsServerInfoListParser - parser for a list of DNS servers, it
creates a DNS server parser for server described in a list of servers
- isc::d2::DnsServerInfoParser - parser for DNS server
- isc::d2::TSIGKeyInfoListParser - parser for a list of TSIG keys, it creates a
parser for key described in a list of keys
- isc::d2::TSIGKeyInfoParser
The underlying common libraries for configuration parsing support configuration
input in JSON format, that complies with a fixed set of generic constructs that
may be described by a spec file (also JSON). This mechanism is subject to
change, but in the meantime, the spec file describe D2's configuration may be
found here: @c src/bin/d2/dhcp-ddns.spec
@section d2NCRReceipt Request Reception and Queueing
D2 is designed to receive requests from Kea's DHCP servers, asynchronously and
store them in queue to be processed. The classes responsible for this are
shown in the diagram below:
@image html request_mgt_classes.svg "Request Management Classes"
- isc::d2::D2QueueMgr - owned by @c D2Process, it listens for @c NameChangeRequests
and queues them for processing. It also provides services for adding,
finding, and removing queue entries. It owns the interface used to receive
requests and thus shields the remainder of D2 from any specific knowledge or
interaction with this interface.
- isc::d2::RequestQueue - storage container for the received requests.
- isc::dhcp_ddns::NameChangeListener - Abstract asynchronous interface for
receiving requests which uses ASIO to process IO and invoke a callback upon
request receipt
- isc::dhcp_ddns::NameChangeUDPListener - Derivation of NameChangeListener
which supports receiving request via UDP socket
- isc::dhcp_ddns::NameChangeRequest - embodies a request to update DNS entries
based upon a DHCP lease change
D2QueueMgr is state-driven, albeit with a very simple state model. The states
are defined by isc::d2::D2QueueMgr::State, and described in detail in in
@ref d2_queue_mgr.h.
@section d2DDNSUpdateExecution Update Execution
The DDNS protocol can lead to a multiple step conversation between the updater
and the DNS server to update entries for a single client. In addition,
@c NameChangeRequests can request changes be made for both forward and reverse
DNS. In order to carry out the appropriate conversation, D2 wraps each request
in a stateful transaction.
Working such transactions serially can be inefficient, especially if those
requests involve different DNS servers. Therefore, D2 has been designed to
work on more than one transaction at a time by creating and managing a list of
transactions.
The classes which are responsible for carrying out this work are shown in the
following diagram:
@image html update_exec_classes.svg "Update Execution Classes"
- isc::d2::D2UpdateMgr owned by @c D2Process, orchestrates the fulfillment of
each request by managing the execution of its transaction. Its high level
method @ref isc::d2::D2UpdateMgr::sweep() is meant to be called whenever IO
events occur. The following steps are performed each time the method is called:
- Any transaction which has been completed, is logged and culled from the
transaction list.
- Start a new transaction for the next queued request (if any)
- isc::d2::NameChangeTransaction - abstract state-driven class which carries
out the steps necessary to fulfill a single request. Fulfilling a request is
achieved as IO events in response it DDNS requests drive the transaction
through its state model. The type of transaction is based on the nature of
the request, this is discussed further on @ref d2TransDetail
- isc::d2::DNSClient - an asynchronous worker which atomically performs a
single DDNS packet exchange with a given server, providing the response via a
callback mechanism. Each time a transaction's state model calls for a packet
exchange with a DNS server, it uses an instance of this class to do it.
- isc::d2::D2UpdateMessage - container for sending and receiving DDNS packets
@section d2EventLoop Main Event Loop
Now that all of the primary components have been introduced it is worth while
discussing D2's main event loop. As mentioned earlier D2 is constructed around
the CPL which is designed to be driven by asynchronous IO processed by a
common IO service thread (isc::asiolink::io_service). Any IO that needs to be
performed by the application thread uses this service to do so. This organizes
the IO event processing into a single event loop centered around the service.
(This does not preclude spinning off worker threads to conduct other tasks,
with their own io_service instances). D2's main event loop, implemented in @ref isc::d2::D2Process::run() may be paraphrased as follows:
@code
As long as we should not shutdown repeat the following steps:
1. Check on the state of the request queue. Take any actions necessary
regarding it. For example, it may be in the process of shutting down
its listener prior to applying a configuration change.
2. Give update manager a "time slice" to cull finished transactions and
start new ones.
3. Block until one or more of the following IO events occur:
a. NCR message has been received
b. Transaction IO has completed
c. Interval timer expired
d. A process command has been received
e. Something has stopped the IO service (most likely a fatal error)
@endcode
@section d2TransDetail Transactions
There are two types of @c NameChangeRequests: an "Add" that is issued when DNS
entries need to be added for new or updated lease, and a "Remove" that is
issued when DNS entries need to be removed for obsolete or expired lease. The
DDNS protocol dictates the steps that should be followed in both cases.
D2's design addresses this by calling for two types of transactions: one for
adding entries and one for removing them, each with their own state model.
The transaction classes are shown in the following diagram:
@image html trans_classes.svg "NameChangeTransaction Derviations"
- isc::d2::NameAddTransaction - carries out a @c NameChangeRequest to add entries
- isc::d2::NameRemoveTransaction - carries out a @c NameChangeRequest to remove entries
- isc::d2::StateModel - abstract state model described in @ref d2StateModel
The state models for these two transactions implement DDNS with conflict
resolution as described in <a href="https://tools.ietf.org/html/rfc4703">RFC 4703</a>.
The state model for isc::d2::NameAddTransaction is diagrammed below:
@image html add_state_model.svg "State Model for NameAddTransaction"
The state model for isc::d2::NameRemoveTransaction is depicted next:
@image html remove_state_model.svg "State Model for NameRemoveTransaction"
@subsection d2StateModel State Model Implementation
D2 implements a abstract state-machine through a light weight set of classes.
At construction, the model's dictionary of events and states is initialized.
This allows, the deriving class the ability to bind a method of its choosing
to each state as that state's handler. Each handler contains the knowledge
of how to respond to the "posted" event and including posting other events and
transitioning to other states.
Executing the model consists of beginning at the current state with the posted
event and continuing until the model needs to wait for an IO-based event or
it has reached the end of the state model. These classes will likely move to
a common library.
@image html state_model_classes.svg "State Model Classes"
- isc::d2::StateModel - provides the mechanics for executing a state model
described by a dictionary events and states. It provides methods to:
- initialize the model - constructs the dictionary of events and states
- start the model - sets the model to its initial state, posts a "start"
event and starts the model "running"
"start event"
- run the model - process the posted event (if one) until the model reaches
a wait state or reaches the end state.
- transition from one state to another
- isc::d2::Event - Defines an event used to stimulate the model
- isc::d2::State - Defines a state with the model, each state has a handler
method that is executed upon transition "into" that state from another
- isc::d2::LabeledValue - An abstract that associates a integer value with a
text label
- isc::d2::LabeledValueSet - A collection of LabeledValues for which the integer
values must be unique
@subsection d2TransExecExample Transaction Execution Example
The following sequence chart depicts the typically sequence of events that occur
when D2UpdateMgr creates and starts executing a transaction:
@image html nc_trans_sequence.svg "Transaction Execution Sequence"
*/
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Bouml (http://bouml.free.fr/) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="749" height="595" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="733" y="357" width="3" height="225" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="627" y="579" width="109" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="623" y="353" width="110" height="226" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="678" y="366">DCfgContextBase</text>
<line stroke="black" stroke-opacity="1" x1="623" y1="368" x2="733" y2="368" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="627" y="381">OPTIONAL</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="627" y="394">REQUIRED</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="407">boolean_values_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="420">uint32_values_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="433">string_values_</text>
<line stroke="black" stroke-opacity="1" x1="623" y1="435" x2="733" y2="435" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="448">DCfgContextBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="461">~DCfgContextBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="474">getParam()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="487">getParam()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="500">getParam()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="513">getBooleanStorage()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="526">getUint32Storage()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="539">getStringStorage()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="627" y="552">clone()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="565">DCfgContextBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="627" y="578">operator =()</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="179" y="15" width="3" height="511" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="35" y="523" width="147" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="31" y="11" width="148" height="512" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="105" y="24">DControllerBase</text>
<line stroke="black" stroke-opacity="1" x1="31" y1="26" x2="179" y2="26" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="39">app_name_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="52">bin_name_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="65">stand_alone_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="78">verbose_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="91">spec_file_name_</text>
<line stroke="black" stroke-opacity="1" x1="31" y1="93" x2="179" y2="93" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="106">DControllerBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="119">~DControllerBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="132">launch()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="145">dummyConfigHandler()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="158">configHandler()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="171">commandHandler()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="184">updateConfig()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="197">executeCommand()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="210">customOption()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="35" y="223">createProcess()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="236">customControllerCommand()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="249">onSessionConnect()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="262">onSessionDisconnect()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="275">getUsageText()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="288">getCustomOpts()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="301">getAppName()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="314">getBinName()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="327">isStandAlone()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="340">setStandAlone()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="353">isVerbose()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="366">setVerbose()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="379">getIOService()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="392">getSpecFileName()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="405">setSpecFileName()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="418">getController()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-decoration="underline" x="35" y="431">setController()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="444">parseArgs()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="457">initProcess()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="470">establishSession()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="483">runProcess()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="496">disconnectSession()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="509">shutdown()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="35" y="522">usage()</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="420" y="119" width="3" height="213" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="324" y="329" width="99" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="320" y="115" width="100" height="214" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="370" y="128">DProcessBase</text>
<line stroke="black" stroke-opacity="1" x1="320" y1="130" x2="420" y2="130" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="143">app_name_</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="156">shut_down_flag_</text>
<line stroke="black" stroke-opacity="1" x1="320" y1="158" x2="420" y2="158" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="171">DProcessBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="184">init()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="197">run()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="210">shutdown()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="223">configure()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="324" y="236">command()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="249">~DProcessBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="262">shouldShutdown()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="275">setShutdownFlag()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="288">getAppName()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="301">getIoService()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="314">stopIOService()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="324" y="327">getCfgMgr()</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="585" y="240" width="3" height="127" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="479" y="364" width="109" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="475" y="236" width="110" height="128" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" font-style="italic" text-anchor="middle" x="530" y="249">DCfgMgrBase</text>
<line stroke="black" stroke-opacity="1" x1="475" y1="251" x2="585" y2="251" />
<line stroke="black" stroke-opacity="1" x1="475" y1="259" x2="585" y2="259" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="272">DCfgMgrBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="285">~DCfgMgrBase()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="298">parseConfig()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="311">addToParseOrder()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="324">getParseOrder()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="337">getContext()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-style="italic" x="479" y="350">createConfigParser()</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="479" y="363">buildAndCommit()</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="419" y="56" width="3" height="45" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="323" y="98" width="99" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="319" y="52" width="100" height="46" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="369" y="65">&lt;&lt;typedef&gt;&gt;</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="369" y="80">DProcessBasePtr</text>
<line stroke="black" stroke-opacity="1" x1="319" y1="82" x2="419" y2="82" />
<line stroke="black" stroke-opacity="1" x1="319" y1="90" x2="419" y2="90" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="371" y1="114" x2="377" y2="108" />
<line stroke="black" stroke-opacity="1" x1="371" y1="114" x2="365" y2="108" />
<line stroke-dasharray="4,4" stroke="black" stroke-opacity="1" x1="371" y1="102" x2="371" y2="114" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="183" y1="34" x2="371" y2="34" />
<polygon fill="#000000" stroke="black" stroke-opacity="1" points="183,34 189,28 195,34 189,40" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="371" y1="51" x2="377" y2="45" />
<line stroke="black" stroke-opacity="1" x1="371" y1="51" x2="365" y2="45" />
<line stroke="black" stroke-opacity="1" x1="371" y1="34" x2="371" y2="51" />
</g>
<g>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="685" y="273">context_</text>
</g>
<g>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="381" y="48">process_</text>
</g>
<g>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="251" y="174">io_service_</text>
</g>
<g>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="535" y="155">cfg_mgr_</text>
</g>
<g>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" x="250" y="244">io_service_</text>
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="275" y="182" width="3" height="45" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="205" y="224" width="73" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="201" y="178" width="74" height="46" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="238" y="191">&lt;&lt;typedef&gt;&gt;</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="238" y="206">IOServicePtr</text>
<line stroke="black" stroke-opacity="1" x1="201" y1="208" x2="275" y2="208" />
<line stroke="black" stroke-opacity="1" x1="201" y1="216" x2="275" y2="216" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="571" y="163" width="3" height="45" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="479" y="205" width="95" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="475" y="159" width="96" height="46" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="523" y="172">&lt;&lt;typedef&gt;&gt;</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="523" y="187">DCfgMgrBasePtr</text>
<line stroke="black" stroke-opacity="1" x1="475" y1="189" x2="571" y2="189" />
<line stroke="black" stroke-opacity="1" x1="475" y1="197" x2="571" y2="197" />
</g>
<g>
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="731" y="281" width="3" height="45" />
<rect fill="#cbcbcb" stroke="none" stroke-opacity="1" x="619" y="323" width="115" height="3" />
<rect fill="#ffffc0" stroke="black" stroke-width="1" stroke-opacity="1" x="615" y="277" width="116" height="46" />
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" text-anchor="middle" x="673" y="290">&lt;&lt;typedef&gt;&gt;</text>
<text font-family="Helvetica" font-size="11" fill="#000000" xml:space="preserve" font-weight="bold" text-anchor="middle" x="673" y="305">DCfgContextBasePtr</text>
<line stroke="black" stroke-opacity="1" x1="615" y1="307" x2="731" y2="307" />
<line stroke="black" stroke-opacity="1" x1="615" y1="315" x2="731" y2="315" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="319" y1="282" x2="240" y2="282" />
<polygon fill="#000000" stroke="black" stroke-opacity="1" points="319,282 313,288 307,282 313,276" />
</g>
<g>
<line stroke="black" stroke-opacity="1" x1="183" y1="154" x2="241" y2="154" />
<polygon fill="#000000" stroke="black" stroke-opacity="1" points="183,154 189,148 195,154 189,160" />