X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FXMLMetadataProvider.cpp;h=6938bce62317b4223e0a70e262ffd4cc32fb8e3d;hp=d47a1d49180c94dbad07927b28eb6a7c52e6652c;hb=f43f417f235f8cd182437d845099f8b76d743298;hpb=86e185cf72d47f6d3250414f7451ece13e7b7ec5 diff --git a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp index d47a1d4..6938bce 100644 --- a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2001-2006 Internet2 - * + * Copyright 2001-2007 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 @@ -16,22 +16,21 @@ /** * XMLMetadataProvider.cpp - * + * * Supplies metadata from an XML file */ #include "internal.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataFilter.h" #include "saml2/metadata/AbstractMetadataProvider.h" -#include #include #include -#include using namespace opensaml::saml2md; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; #if defined (_MSC_VER) @@ -45,7 +44,10 @@ namespace opensaml { class SAML_DLLLOCAL XMLMetadataProvider : public AbstractMetadataProvider, public ReloadableXMLFile { public: - XMLMetadataProvider(const DOMElement* e) : AbstractMetadataProvider(e), ReloadableXMLFile(e), m_object(NULL) {} + XMLMetadataProvider(const DOMElement* e) + : AbstractMetadataProvider(e), ReloadableXMLFile(e, Category::getInstance(SAML_LOGCAT".MetadataProvider.XML")), + m_object(NULL), m_maxCacheDuration(m_reloadInterval) { + } virtual ~XMLMetadataProvider() { delete m_object; } @@ -53,18 +55,21 @@ namespace opensaml { void init() { load(); // guarantees an exception or the metadata is loaded } - - pair load(); const XMLObject* getMetadata() const { return m_object; } + protected: + pair load(); + private: + using AbstractMetadataProvider::index; void index(); - + XMLObject* m_object; - }; + time_t m_maxCacheDuration; + }; MetadataProvider* SAML_DLLLOCAL XMLMetadataProviderFactory(const DOMElement* const & e) { @@ -80,50 +85,60 @@ namespace opensaml { pair XMLMetadataProvider::load() { -#ifdef _DEBUG - NDC ndc("load"); -#endif - - try { - // Load from source using base class. - pair raw = ReloadableXMLFile::load(); - - // If we own it, wrap it for now. - XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL); - - // Unmarshall objects, binding the document. - XMLObject* xmlObject=XMLObjectBuilder::buildOneFromElement(raw.second, true); - docjanitor.release(); - - // Preprocess the metadata. - auto_ptr xmlObjectPtr(xmlObject); - doFilters(*xmlObject); - xmlObjectPtr->releaseThisAndChildrenDOM(); - xmlObjectPtr->setDocument(NULL); - - // Swap it in. - bool changed = m_object!=NULL; - delete m_object; - m_object = xmlObjectPtr.release(); - index(); - if (changed) - emitChangeEvent(); - return make_pair(false,(DOMElement*)NULL); - } - catch (XMLToolingException& e) { - Category::getInstance(SAML_LOGCAT".Metadata").error("error while loading metadata: %s", e.what()); - throw; + // Load from source using base class. + pair raw = ReloadableXMLFile::load(); + + // If we own it, wrap it for now. + XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL); + + // Unmarshall objects, binding the document. + auto_ptr xmlObject(XMLObjectBuilder::buildOneFromElement(raw.second, true)); + docjanitor.release(); + + if (!dynamic_cast(xmlObject.get()) && !dynamic_cast(xmlObject.get())) + throw MetadataException( + "Root of metadata instance not recognized: $1", params(1,xmlObject->getElementQName().toString().c_str()) + ); + + // Preprocess the metadata. + doFilters(*xmlObject.get()); + xmlObject->releaseThisAndChildrenDOM(); + xmlObject->setDocument(NULL); + + // Swap it in. + bool changed = m_object!=NULL; + delete m_object; + m_object = xmlObject.release(); + index(); + if (changed) + emitChangeEvent(); + + // If a remote resource, reduce the reload interval if cacheDuration is set. + if (!m_local) { + const CacheableSAMLObject* cacheable = dynamic_cast(m_object); + if (cacheable && cacheable->getCacheDuration() && cacheable->getCacheDurationEpoch() < m_maxCacheDuration) + m_reloadInterval = cacheable->getCacheDurationEpoch(); + else + m_reloadInterval = m_maxCacheDuration; } + + return make_pair(false,(DOMElement*)NULL); } void XMLMetadataProvider::index() { + time_t exp = SAMLTIME_MAX; + clearDescriptorIndex(); EntitiesDescriptor* group=dynamic_cast(m_object); if (group) { - AbstractMetadataProvider::index(group, SAMLTIME_MAX); + if (!m_local && group->getCacheDuration()) + exp = time_t(NULL) + group->getCacheDurationEpoch(); + AbstractMetadataProvider::index(group, exp); return; } EntityDescriptor* site=dynamic_cast(m_object); - AbstractMetadataProvider::index(site, SAMLTIME_MAX); + if (!m_local && site->getCacheDuration()) + exp = time_t(NULL) + site->getCacheDurationEpoch(); + AbstractMetadataProvider::index(site, exp); }