4f211773037c454861717d8b65cdaf13c04fb8f9
[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          * Preserves the last remote resource caching identifier in a backup file
155          * for use on the next restart.
156          */
157         void preserveCacheTag();
158
159         /**
160          * Starts up reload thread, can be automatically called by constructor, or
161          * manually invoked by subclass.
162          */
163         void startup();
164
165         /**
166          * Shuts down reload thread, should be called from subclass destructor.
167          */
168         void shutdown();
169
170         /** Root of the original DOM element passed into constructor. */
171         const xercesc::DOMElement* m_root;
172         
173         /** Indicates whether resources is local or remote. */
174         bool m_local;
175         
176         /** Use a validating parser when parsing XML. */
177         bool m_validate;
178         
179         /** Resource location, may be a local path or a URI. */
180         std::string m_source;
181
182         /** Path to backup copy for remote resource. */
183         std::string m_backing;
184
185         /** Last modification of local resource. */
186         time_t m_filestamp;
187
188         /** Time in seconds to wait before trying for new copy of remote resource. */
189         time_t m_reloadInterval;
190
191         /** Caching tag associated with remote resource. */
192         std::string m_cacheTag;
193
194         /** Shared lock for guarding reloads. */
195         RWLock* m_lock;
196         
197         /** Logging object. */
198         logging::Category& m_log;
199
200         /** Plugin identifier. */
201         std::string m_id;
202
203         /** Indicates whether a usable version of the resource is in place. */
204         bool m_loaded;
205
206 #ifndef XMLTOOLING_LITE
207         /** CredentialResolver for signature verification. */
208         CredentialResolver* m_credResolver;
209
210         /** TrustEngine for signature verification. */
211         SignatureTrustEngine* m_trust;
212
213         /** Name of signer for signature verification. */
214         std::string m_signerName;
215 #endif
216
217     public:
218         Lockable* lock();
219         void unlock();
220
221     private:
222 #ifndef XMLTOOLING_LITE
223         void validateSignature(xmlsignature::Signature& sigObj) const;
224 #endif
225         // Used to manage background reload/refresh.
226         bool m_shutdown;
227         CondWait* m_reload_wait;
228         Thread* m_reload_thread;
229         static void* reload_fn(void*);
230     };
231
232 };
233
234 #endif /* __xmltooling_reloadable_h__ */