43018969438708420a55fb99c0e3e9582ab9124e
[shibboleth/cpp-xmltooling.git] / xmltooling / util / ReloadableXMLFile.h
1 /*
2  *  Copyright 2001-2010 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file xmltooling/util/ReloadableXMLFile.h
19  * 
20  * Base class for file-based XML configuration.
21  */
22
23 #ifndef __xmltooling_reloadable_h__
24 #define __xmltooling_reloadable_h__
25
26 #include <xmltooling/logging.h>
27 #include <xmltooling/Lockable.h>
28
29 #include <ctime>
30 #include <string>
31 #include <xercesc/dom/DOM.hpp>
32
33 #ifndef XMLTOOLING_LITE
34     namespace xmlsignature {
35         class XMLTOOL_API Signature;
36     };
37 #endif
38
39 namespace xmltooling {
40
41     class XMLTOOL_API CondWait;
42     class XMLTOOL_API RWLock;
43     class XMLTOOL_API Thread;
44
45 #ifndef XMLTOOLING_LITE
46     class XMLTOOL_API CredentialResolver;
47     class XMLTOOL_API SignatureTrustEngine;
48 #endif
49
50     /**
51      * Base class for file-based XML configuration.
52      */
53     class XMLTOOL_API ReloadableXMLFile : protected virtual Lockable
54     {
55     MAKE_NONCOPYABLE(ReloadableXMLFile);
56     protected:
57         /**
58          * Constructor taking a DOM element supporting the following content:
59          * 
60          * <dl>
61          *  <dt>file | filename | path | pathname</dt>
62          *  <dd>identifies a local file</dd>
63          *  <dt>uri | url</dt>
64          *  <dd>identifies a remote resource</dd>
65          *  <dt>validate</dt>
66          *  <dd>use a validating parser</dd>
67          *  <dt>reloadChanges</dt>
68          *  <dd>enables monitoring of local file for changes</dd>
69          *  <dt>reloadInterval or maxRefreshDelay</dt>
70          *  <dd>enables periodic refresh of remote file</dd>
71          *  <dt>backingFilePath</dt>
72          *  <dd>location for backup of remote resource</dd>
73          *  <dt>id</dt>
74          *  <dd>identifies the plugin instance for logging purposes</dd>
75          *  <dt>certificate</dt>
76          *  <dd>requires XML be signed with an enveloped signature verifiable with specified key</dd>
77          *  <dt>signerName</dt>
78          *  <dd>requires XML be signed with an enveloped signature verifiable with &lt;TrustEngine&gt;
79          *      by certificate containing this name</dd>
80          *  <dt>&lt;CredentialResolver&gt;</dt>
81          *  <dd>requires XML be signed with an enveloped signature verifiable with specified key</dd>
82          *  <dt>&lt;TrustEngine&gt;</dt>
83          *  <dd>requires XML be signed with an enveloped signature verifiable with specified TrustEngine</dd>
84          * </dl>
85          * 
86          * @param e                 DOM to supply configuration
87          * @param log               logging object to use
88          * @param startReloadThread true iff refresh thread for resources should be started by constructor
89          */
90         ReloadableXMLFile(const xercesc::DOMElement* e, logging::Category& log, bool startReloadThread=true);
91     
92         virtual ~ReloadableXMLFile();
93
94         /**
95          * Loads configuration material.
96          * 
97          * <p>This method is called to load configuration material
98          * initially and any time a change is detected. The base version
99          * performs basic parsing duties and returns the result.
100          *
101          * <p>This method is not called with the object locked, so actual
102          * modification of implementation state requires explicit locking within
103          * the method override.
104          * 
105          * @return a pair consisting of a flag indicating whether to take ownership of
106          *      the document, and the root element of the tree to load
107          */
108         virtual std::pair<bool,xercesc::DOMElement*> background_load();
109
110         /**
111          * @deprecated
112          * Basic load/parse of configuration material.
113          * 
114          * <p>The base version performs basic parsing duties and returns the result.
115          * Subclasses should override the new background_load() method and perform
116          * their own locking in conjunction with use of this method.
117          *
118          * <p>Subclasses that continue to override this method will function, but
119          * a write lock will be acquired and held for the entire operation.
120          * 
121          * @return a pair consisting of a flag indicating whether to take ownership of
122          *      the document, and the root element of the tree to load
123          */
124         virtual std::pair<bool,xercesc::DOMElement*> load();
125
126         /**
127          * Basic load/parse of configuration material.
128          *
129          * <p>The base version performs basic parsing duties and returns the result.
130          * Subclasses should override the new background_load() method and perform
131          * their own locking in conjunction with use of this method.
132          *
133          * <p>This version allows subclasses to explicitly control the use of a
134          * backup for remote resources, which allows additional validation to be
135          * performed besides just successful XML parsing.
136          *
137          * @param backup    true iff the backup source should be loaded
138          * @return a pair consisting of a flag indicating whether to take ownership of
139          *      the document, and the root element of the tree to load
140          */
141         virtual std::pair<bool,xercesc::DOMElement*> load(bool backup);
142
143         /**
144          * Accesses a lock interface protecting use of backup file associated with the
145          * object.
146          *
147          * <p>The lock is <strong>NOT</strong> acquired automatically.
148          *
149          * @return  pointer to a lock interface, or nullptr if unnecessary
150          */
151         virtual Lockable* getBackupLock();
152
153         /**
154          * Starts up reload thread, can be automatically called by constructor, or
155          * manually invoked by subclass.
156          */
157         void startup();
158
159         /**
160          * Shuts down reload thread, should be called from subclass destructor.
161          */
162         void shutdown();
163
164         /** Root of the original DOM element passed into constructor. */
165         const xercesc::DOMElement* m_root;
166         
167         /** Indicates whether resources is local or remote. */
168         bool m_local;
169         
170         /** Use a validating parser when parsing XML. */
171         bool m_validate;
172         
173         /** Resource location, may be a local path or a URI. */
174         std::string m_source;
175
176         /** Path to backup copy for remote resource. */
177         std::string m_backing;
178
179         /** Last modification of local resource. */
180         time_t m_filestamp;
181
182         /** Time in seconds to wait before trying for new copy of remote resource. */
183         time_t m_reloadInterval;
184
185         /** Caching tag associated with remote resource. */
186         std::string m_cacheTag;
187
188         /** Shared lock for guarding reloads. */
189         RWLock* m_lock;
190         
191         /** Logging object. */
192         logging::Category& m_log;
193
194         /** Plugin identifier. */
195         std::string m_id;
196
197         /** Indicates whether a usable version of the resource is in place. */
198         bool m_loaded;
199
200 #ifndef XMLTOOLING_LITE
201         /** CredentialResolver for signature verification. */
202         CredentialResolver* m_credResolver;
203
204         /** TrustEngine for signature verification. */
205         SignatureTrustEngine* m_trust;
206
207         /** Name of signer for signature verification. */
208         std::string m_signerName;
209 #endif
210
211     public:
212         Lockable* lock();
213         void unlock();
214
215     private:
216 #ifndef XMLTOOLING_LITE
217         void validateSignature(xmlsignature::Signature& sigObj) const;
218 #endif
219         // Used to manage background reload/refresh.
220         bool m_shutdown;
221         CondWait* m_reload_wait;
222         Thread* m_reload_thread;
223         static void* reload_fn(void*);
224     };
225
226 };
227
228 #endif /* __xmltooling_reloadable_h__ */