Branch data Line data Source code
1 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <string>
16 : :
17 : : #include <exceptions/exceptions.h>
18 : :
19 : : #include <cc/data.h>
20 : :
21 : : #ifndef __CONFIG_H
22 : : #define __CONFIG_H 1
23 : :
24 : : class AuthSrv;
25 : :
26 : : /// An exception that is thrown if an error occurs while configuring an
27 : : /// \c AuthSrv object.
28 : 23 : class AuthConfigError : public isc::Exception {
29 : : public:
30 : 23 : AuthConfigError(const char* file, size_t line, const char* what) :
31 : 23 : isc::Exception(file, line, what) {}
32 : : };
33 : :
34 : : /// The abstract base class that represents a single configuration identifier
35 : : /// for an \c AuthSrv object.
36 : : ///
37 : : /// In general, each top level configuration identifier for \c AuthSrv is
38 : : /// expected to have its own derived class of this base class.
39 : : /// For example, for the following configuration:
40 : : /// \code { "param1": 10, "param2": { "subparam1": "foo", "subparam2": [] } }
41 : : /// \endcode
42 : : /// "param1" and "param2" are top level identifiers, and would correspond to
43 : : /// derived \c AuthConfigParser classes.
44 : : /// "subparam1" and/or "subparam2" may also have dedicated derived classes.
45 : : ///
46 : : /// These derived classes are hidden inside the implementation; applications
47 : : /// are not expected to (and in fact cannot) instantiate them directly.
48 : : ///
49 : : /// Each derived class is generally expected to be constructed with an
50 : : /// \c AuthSrv object to be configured and hold a reference to the server
51 : : /// throughout the configuration process.
52 : : /// For each derived class, the \c build() method parses the configuration
53 : : /// value for the corresponding identifier and prepares new configuration
54 : : /// value(s) to be applied to the server. This method may throw an exception
55 : : /// when it encounters an error.
56 : : /// The \c commit() method actually applies the new configuration value
57 : : /// to the server. It's basically not expected to throw an exception;
58 : : /// any configuration operations that can fail (such as ones involving
59 : : /// resource allocation) should be done in \c build().
60 : : ///
61 : : /// When the destructor is called before \c commit(), the destructor is
62 : : /// supposed to make sure the state of the \c AuthSrv object is the same
63 : : /// as that before it starts building the configuration value.
64 : : /// If \c build() doesn't change the server state (which is recommended)
65 : : /// the destructor doesn't have to do anything special in this regard.
66 : : /// This is a key to ensure the strong exception guarantee (see also
67 : : /// the description of \c configureAuthServer()).
68 : : class AuthConfigParser {
69 : : ///
70 : : /// \name Constructors and Destructor
71 : : ///
72 : : /// Note: The copy constructor and the assignment operator are
73 : : /// intentionally defined as private to make it explicit that this is a
74 : : /// pure base class.
75 : : //@{
76 : : private:
77 : : AuthConfigParser(const AuthConfigParser& source);
78 : : AuthConfigParser& operator=(const AuthConfigParser& source);
79 : : protected:
80 : : /// \brief The default constructor.
81 : : ///
82 : : /// This is intentionally defined as \c protected as this base class should
83 : : /// never be instantiated (except as part of a derived class).
84 : 96 : AuthConfigParser() {}
85 : : public:
86 : : /// The destructor.
87 : 96 : virtual ~AuthConfigParser() {}
88 : : //@}
89 : :
90 : : /// Prepare configuration value.
91 : : ///
92 : : /// This method parses the "value part" of the configuration identifier
93 : : /// that corresponds to this derived class and prepares a new value to
94 : : /// apply to the server.
95 : : /// In the above example, the derived class for the identifier "param1"
96 : : /// would be passed an data \c Element storing an integer whose value
97 : : /// is 10, and would record that value internally;
98 : : /// the derived class for the identifier "param2" would be passed a
99 : : /// map element and (after parsing) convert it into some internal
100 : : /// data structure.
101 : : ///
102 : : /// This method must validate the given value both in terms of syntax
103 : : /// and semantics of the configuration, so that the server will be
104 : : /// validly configured at the time of \c commit(). Note: the given
105 : : /// configuration value is normally syntactically validated, but the
106 : : /// \c build() implementation must also expect invalid input. If it
107 : : /// detects an error it may throw an exception of a derived class
108 : : /// of \c isc::Exception.
109 : : ///
110 : : /// Preparing a configuration value will often require resource
111 : : /// allocation. If it fails, it may throw a corresponding standard
112 : : /// exception.
113 : : ///
114 : : /// This method is not expected to be called more than once. Although
115 : : /// multiple calls are not prohibited by the interface, the behavior
116 : : /// is undefined.
117 : : ///
118 : : /// \param config_value The configuration value for the identifier
119 : : /// corresponding to the derived class.
120 : : virtual void build(isc::data::ConstElementPtr config_value) = 0;
121 : :
122 : : /// Apply the prepared configuration value to the server.
123 : : ///
124 : : /// This method is expected to be exception free, and, as a consequence,
125 : : /// it should normally not involve resource allocation.
126 : : /// Typically it would simply perform exception free assignment or swap
127 : : /// operation on the value prepared in \c build().
128 : : /// In some cases, however, it may be very difficult to meet this
129 : : /// condition in a realistic way, while the failure case should really
130 : : /// be very rare. In such a case it may throw, and, if the parser is
131 : : /// called via \c configureAuthServer(), the caller will convert the
132 : : /// exception as a fatal error.
133 : : ///
134 : : /// This method is expected to be called after \c build(), and only once.
135 : : /// The result is undefined otherwise.
136 : : virtual void commit() = 0;
137 : : };
138 : :
139 : : /// Configure an \c AuthSrv object with a set of configuration values.
140 : : ///
141 : : /// This function parses configuration information stored in \c config_set
142 : : /// and configures the \c server by applying the configuration to it.
143 : : /// It provides the strong exception guarantee as long as the underlying
144 : : /// derived class implementations of \c AuthConfigParser meet the assumption,
145 : : /// that is, it ensures that either configuration is fully applied or the
146 : : /// state of the server is intact.
147 : : ///
148 : : /// If a syntax or semantics level error happens during the configuration
149 : : /// (such as malformed configuration or invalid configuration parameter),
150 : : /// this function throws an exception of class \c AuthConfigError.
151 : : /// If the given configuration requires resource allocation and it fails,
152 : : /// a corresponding standard exception will be thrown.
153 : : /// Other exceptions may also be thrown, depending on the implementation of
154 : : /// the underlying derived class of \c AuthConfigError.
155 : : /// In any case the strong guarantee is provided as described above except
156 : : /// in the very rare cases where the \c commit() method of a parser throws
157 : : /// an exception. If that happens this function converts the exception
158 : : /// into a \c FatalError exception and rethrows it. This exception is
159 : : /// expected to be caught at the highest level of the application to terminate
160 : : /// the program gracefully.
161 : : ///
162 : : /// \param server The \c AuthSrv object to be configured.
163 : : /// \param config_set A JSON style configuration to apply to \c server.
164 : : void configureAuthServer(AuthSrv& server,
165 : : isc::data::ConstElementPtr config_set);
166 : :
167 : : /// Create a new \c AuthConfigParser object for a given configuration
168 : : /// identifier.
169 : : ///
170 : : /// It internally identifies an appropriate derived class for the given
171 : : /// identifier and creates a new instance of that class. The caller can
172 : : /// then configure the \c server regarding the identifier by calling
173 : : /// the \c build() and \c commit() methods of the returned object.
174 : : ///
175 : : /// In practice, this function is only expected to be used as a backend of
176 : : /// \c configureAuthServer() and is not supposed to be called directly
177 : : /// by applications. It is publicly available mainly for testing purposes.
178 : : /// When called directly, the created object must be deleted by the caller.
179 : : /// Note: this means if this module and the caller use incompatible sets of
180 : : /// new/delete, it may cause unexpected strange failure. We could avoid that
181 : : /// by providing a separate deallocation function or by using a smart pointer,
182 : : /// but since the expected usage of this function is very limited (i.e. for
183 : : /// our own testing purposes) it would be an overkilling. We therefore prefer
184 : : /// simplicity and keeping the interface intuitive.
185 : : ///
186 : : /// If the resource allocation for the new object fails, a corresponding
187 : : /// standard exception will be thrown. Otherwise this function is not
188 : : /// expected to throw an exception, unless the constructor of the underlying
189 : : /// derived class implementation (unexpectedly) throws.
190 : : ///
191 : : /// \param server The \c AuthSrv object to be configured.
192 : : /// \param config_id The configuration identifier for which a parser object
193 : : /// is to be created.
194 : : /// \return A pointer to an \c AuthConfigParser object.
195 : : AuthConfigParser* createAuthConfigParser(AuthSrv& server,
196 : : const std::string& config_id);
197 : :
198 : : #endif // __CONFIG_H
199 : :
200 : : // Local Variables:
201 : : // mode: c++
202 : : // End:
|