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