From 5b37e4a8d91373f6ed42ef77d1de39526d1d271c Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Sun, 13 Aug 2006 01:32:49 +0000 Subject: [PATCH] Add metadata observation hook. --- saml/Makefile.am | 4 +- saml/saml.vcproj | 8 ++ saml/saml2/metadata/MetadataProvider.h | 2 +- saml/saml2/metadata/ObservableMetadataProvider.h | 106 +++++++++++++++++++++ .../metadata/impl/FilesystemMetadataProvider.cpp | 8 +- saml/saml2/metadata/impl/MetadataProvider.cpp | 2 +- .../metadata/impl/ObservableMetadataProvider.cpp | 39 ++++++++ 7 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 saml/saml2/metadata/ObservableMetadataProvider.h create mode 100644 saml/saml2/metadata/impl/ObservableMetadataProvider.cpp diff --git a/saml/Makefile.am b/saml/Makefile.am index 31abc1a..36e8611 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -49,7 +49,8 @@ saml2coreinclude_HEADERS = \ saml2mdinclude_HEADERS = \ saml2/metadata/Metadata.h saml2/metadata/MetadataFilter.h \ - saml2/metadata/MetadataProvider.h + saml2/metadata/MetadataProvider.h \ + saml2/metadata/ObservableMetadataProvider.h noinst_HEADERS = \ internal.h @@ -75,6 +76,7 @@ libsaml_la_SOURCES = \ saml2/metadata/impl/MetadataImpl.cpp \ saml2/metadata/impl/MetadataProvider.cpp \ saml2/metadata/impl/MetadataSchemaValidators.cpp \ + saml2/metadata/impl/ObservableMetadataProvider.cpp \ saml2/metadata/impl/WhitelistMetadataFilter.cpp \ signature/ContentReference.cpp \ signature/SignatureProfileValidator.cpp \ diff --git a/saml/saml.vcproj b/saml/saml.vcproj index 58ba323..ce4d609 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -315,6 +315,10 @@ > + + @@ -449,6 +453,10 @@ RelativePath=".\saml2\metadata\MetadataProvider.h" > + + m_filters; diff --git a/saml/saml2/metadata/ObservableMetadataProvider.h b/saml/saml2/metadata/ObservableMetadataProvider.h new file mode 100644 index 0000000..e1b1ae5 --- /dev/null +++ b/saml/saml2/metadata/ObservableMetadataProvider.h @@ -0,0 +1,106 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file saml/saml2/metadata/ObservableMetadataProvider.h + * + * A metadata provider that notifies interested parties of changes. + */ + +#ifndef __saml2_obsmetadataprov_h__ +#define __saml2_obsmetadataprov_h__ + +#include + +namespace opensaml { + + namespace saml2md { + + /** + * A metadata provider that notifies interested parties of changes. + */ + class SAML_API ObservableMetadataProvider : public MetadataProvider + { + protected: + /** + * Constructor. + * + * @param e DOM to supply configuration for provider + */ + ObservableMetadataProvider(const DOMElement* e) : MetadataProvider(e) {} + + /** + * Convenience method for notifying every registered Observer of an event. + */ + void emitChangeEvent(); + + public: + /** + * Destructor will delete any installed filters. + */ + virtual ~ObservableMetadataProvider(); + + /** + * An observer of metadata provider changes. + */ + class SAML_API Observer { + MAKE_NONCOPYABLE(Observer); + protected: + Observer() {} + public: + virtual ~Observer() {} + + /** + * Called when a provider signals an event has occured. + * The provider is already locked. + * + * @param provider the provider being observed + */ + virtual void onEvent(MetadataProvider& provider)=0; + }; + + /** + * Adds a metadata observer. + * + * @param newObserver metadata observer to add + */ + virtual void addObserver(Observer* newObserver) { + m_observers.push_back(newObserver); + } + + /** + * Removes a metadata observer. The caller must delete the observer if necessary. + * + * @param oldObserver metadata observer to remove + * @return the old observer + */ + virtual Observer* removeObserver(Observer* oldObserver) { + for (std::vector::iterator i=m_observers.begin(); i!=m_observers.end(); i++) { + if (oldObserver==(*i)) { + m_observers.erase(i); + return oldObserver; + } + } + return NULL; + } + + private: + std::vector m_observers; + }; + }; +}; + +#endif /* __saml2_obsmetadataprov_h__ */ diff --git a/saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp b/saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp index 51c2b83..6b5a256 100644 --- a/saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp @@ -21,7 +21,7 @@ */ #include "internal.h" -#include "saml2/metadata/MetadataProvider.h" +#include "saml2/metadata/ObservableMetadataProvider.h" #include #include @@ -41,7 +41,7 @@ namespace opensaml { namespace saml2md { - class SAML_DLLLOCAL FilesystemMetadataProvider : public MetadataProvider + class SAML_DLLLOCAL FilesystemMetadataProvider : public ObservableMetadataProvider { public: FilesystemMetadataProvider(const DOMElement* e); @@ -88,7 +88,7 @@ static const XMLCh filename[] = UNICODE_LITERAL_8(f,i,l,e,n,a,m,e); static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e); FilesystemMetadataProvider::FilesystemMetadataProvider(const DOMElement* e) - : MetadataProvider(e), m_root(e), m_filestamp(0), m_validate(false), m_lock(NULL), m_object(NULL) + : ObservableMetadataProvider(e), m_root(e), m_filestamp(0), m_validate(false), m_lock(NULL), m_object(NULL) { #ifdef _DEBUG NDC ndc("FilesystemMetadataProvider"); @@ -234,6 +234,7 @@ Lockable* FilesystemMetadataProvider::lock() delete m_object; m_object = newstuff; index(); + emitChangeEvent(); } catch(XMLToolingException& e) { Category::getInstance(SAML_LOGCAT".Metadata").error("failed to reload metadata from file, sticking with what we have: %s", e.what()); @@ -250,6 +251,7 @@ Lockable* FilesystemMetadataProvider::lock() void FilesystemMetadataProvider::index() { + clearDescriptorIndex(); EntitiesDescriptor* group=dynamic_cast(m_object); if (group) { MetadataProvider::index(group, SAMLTIME_MAX); diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp index 2a7052e..049cb6b 100644 --- a/saml/saml2/metadata/impl/MetadataProvider.cpp +++ b/saml/saml2/metadata/impl/MetadataProvider.cpp @@ -191,7 +191,7 @@ void MetadataProvider::index(EntitiesDescriptor* group, time_t validUntil) index(*j,group->getValidUntilEpoch()); } -void MetadataProvider::clearIndex() +void MetadataProvider::clearDescriptorIndex() { m_sources.clear(); m_sites.clear(); diff --git a/saml/saml2/metadata/impl/ObservableMetadataProvider.cpp b/saml/saml2/metadata/impl/ObservableMetadataProvider.cpp new file mode 100644 index 0000000..569c030 --- /dev/null +++ b/saml/saml2/metadata/impl/ObservableMetadataProvider.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * ObservableMetadataProvider.cpp + * + * A metadata provider that notifies interested parties of changes. + */ + +#include "internal.h" +#include "saml2/metadata/ObservableMetadataProvider.h" + +using namespace opensaml::saml2md; +using namespace std; + +ObservableMetadataProvider::~ObservableMetadataProvider() +{ + for_each(m_observers.begin(),m_observers.end(),xmltooling::cleanup()); +} + +void ObservableMetadataProvider::emitChangeEvent() +{ + for (std::vector::const_iterator i=m_observers.begin(); i!=m_observers.end(); i++) { + (*i)->onEvent(*this); + } +} -- 2.1.4