1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef D_PROCESS_H
#define D_PROCESS_H
#include <asiolink/io_service.h>
#include <cc/data.h>
#include <process/d_cfg_mgr.h>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
namespace isc {
namespace process {
/// @brief Exception thrown if the process encountered an operational error.
class DProcessBaseError : public isc::Exception {
public:
DProcessBaseError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief String value for the shutdown command.
static const std::string SHUT_DOWN_COMMAND("shutdown");
/// @brief Returned by the process to indicate a command was successful.
static const int COMMAND_SUCCESS = 0;
/// @brief Returned by the process to indicates a command failed.
static const int COMMAND_ERROR = 1;
/// @brief Returned by the process to indicates a command is not valid.
static const int COMMAND_INVALID = 2;
/// @brief Application Process Interface
///
/// DProcessBase is an abstract class represents the primary "application"
/// level object in a "managed" asynchronous application. It provides a uniform
/// interface such that a managing layer can construct, initialize, and start
/// the application's event loop. The event processing is centered around the
/// use of isc::asiolink::io_service. The io_service is shared between the
/// managing layer and the DProcessBase. This allows management layer IO such
/// as directives to be sensed and handled, as well as processing IO activity
/// specific to the application. In terms of management layer IO, there are
/// methods shutdown, configuration updates, and commands unique to the
/// application.
class DProcessBase {
public:
/// @brief Constructor
///
/// @param app_name is a text label for the process. Generally used
/// in log statements, but otherwise arbitrary.
/// @param io_service is the io_service used by the caller for
/// asynchronous event handling.
/// @param cfg_mgr the configuration manager instance that handles
/// configuration parsing.
///
/// @throw DProcessBaseError is io_service is NULL.
DProcessBase(const char* app_name, asiolink::IOServicePtr io_service,
DCfgMgrBasePtr cfg_mgr)
: app_name_(app_name), io_service_(io_service), shut_down_flag_(false),
cfg_mgr_(cfg_mgr) {
if (!io_service_) {
isc_throw (DProcessBaseError, "IO Service cannot be null");
}
if (!cfg_mgr_) {
isc_throw (DProcessBaseError, "CfgMgr cannot be null");
}
};
/// @brief May be used after instantiation to perform initialization unique
/// to application. It must be invoked prior to invoking run. This would
/// likely include the creation of additional IO sources and their
/// integration into the io_service.
/// @throw DProcessBaseError if the initialization fails.
virtual void init() = 0;
/// @brief Implements the process's event loop. In its simplest form it
/// would an invocation io_service_->run(). This method should not exit
/// until the process itself is exiting due to a request to shutdown or
/// some anomaly is forcing an exit.
/// @throw DProcessBaseError if an operational error is encountered.
virtual void run() = 0;
/// @brief Initiates the process's shutdown process.
///
/// This is last step in the shutdown event callback chain, that is
/// intended to notify the process it is to begin its shutdown process.
///
/// @param args an Element set of shutdown arguments (if any) that are
/// supported by the process derivation.
///
/// @return an Element that contains the results of argument processing,
/// consisting of an integer status value (0 means successful,
/// non-zero means failure), and a string explanation of the outcome.
///
/// @throw DProcessBaseError if an operational error is encountered.
virtual isc::data::ConstElementPtr
shutdown(isc::data::ConstElementPtr args) = 0;
/// @brief Processes the given configuration.
///
/// This method may be called multiple times during the process lifetime.
/// Certainly once during process startup, and possibly later if the user
/// alters configuration. This method must not throw, it should catch any
/// processing errors and return a success or failure answer as described
/// below.
///
/// @param config_set a new configuration (JSON) for the process
/// @param check_only true if configuration is to be verified only, not applied
/// @return an Element that contains the results of configuration composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr
configure(isc::data::ConstElementPtr config_set,
bool check_only = false) = 0;
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// @return an Element that contains the results of command composed
/// of an integer status value:
///
/// - COMMAND_SUCCESS indicates a command was successful.
/// - COMMAND_ERROR indicates a valid command failed execute.
/// - COMMAND_INVALID indicates a command is not valid.
///
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr command(
const std::string& command, isc::data::ConstElementPtr args) = 0;
/// @brief Destructor
virtual ~DProcessBase(){};
/// @brief Checks if the process has been instructed to shut down.
///
/// @return true if process shutdown flag is true.
bool shouldShutdown() const {
return (shut_down_flag_);
}
/// @brief Sets the process shut down flag to the given value.
///
/// @param value is the new value to assign the flag.
void setShutdownFlag(bool value) {
shut_down_flag_ = value;
}
/// @brief Fetches the application name.
///
/// @return application name string.
const std::string getAppName() const {
return (app_name_);
}
/// @brief Fetches the controller's IOService.
///
/// @return a reference to the controller's IOService.
asiolink::IOServicePtr& getIoService() {
return (io_service_);
}
/// @brief Convenience method for stopping IOservice processing.
/// Invoking this will cause the process to exit any blocking
/// IOService method such as run(). No further IO events will be
/// processed.
void stopIOService() {
io_service_->stop();
}
/// @brief Fetches the process's configuration manager.
///
/// @return a reference to the configuration manager.
DCfgMgrBasePtr& getCfgMgr() {
return (cfg_mgr_);
}
private:
/// @brief Text label for the process. Generally used in log statements,
/// but otherwise can be arbitrary.
std::string app_name_;
/// @brief The IOService to be used for asynchronous event handling.
asiolink::IOServicePtr io_service_;
/// @brief Boolean flag set when shutdown has been requested.
bool shut_down_flag_;
/// @brief Pointer to the configuration manager.
DCfgMgrBasePtr cfg_mgr_;
};
/// @brief Defines a shared pointer to DProcessBase.
typedef boost::shared_ptr<DProcessBase> DProcessBasePtr;
}; // namespace isc::process
}; // namespace isc
#endif
|