[opensaml2] 05/11: SSPCPP-756 Split Out AbstractDynamicMetadatProvider
Etienne Dysli Metref
edm-guest at moszumanska.debian.org
Thu Nov 16 08:08:24 UTC 2017
This is an automated email from the git hooks/post-receive script.
edm-guest pushed a commit to branch master
in repository opensaml2.
commit cf209509c1fd28ce609813c5691df42f650baecb
Author: Rod Widdowson <rdw at steadingsoftware.com>
Date: Sat Nov 4 16:31:44 2017 +0000
SSPCPP-756 Split Out AbstractDynamicMetadatProvider
https://issues.shibboleth.net/jira/browse/SSPCPP-756
---
Projects/vc15/saml/saml.vcxproj | 2 +
Projects/vc15/saml/saml.vcxproj.filters | 6 +
saml/Makefile.am | 2 +
...rovider.h => AbstractDynamicMetadataProvider.h} | 13 +-
saml/saml2/metadata/DynamicMetadataProvider.h | 47 +---
...der.cpp => AbstractDynamicMetadataProvider.cpp} | 87 +-----
.../metadata/impl/DynamicMetadataProvider.cpp | 310 +--------------------
7 files changed, 35 insertions(+), 432 deletions(-)
diff --git a/Projects/vc15/saml/saml.vcxproj b/Projects/vc15/saml/saml.vcxproj
index 3ffcce2..ed2c18d 100644
--- a/Projects/vc15/saml/saml.vcxproj
+++ b/Projects/vc15/saml/saml.vcxproj
@@ -188,6 +188,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClCompile Include="..\..\..\saml\saml2\metadata\impl\AbstractDynamicMetadataProvider.cpp" />
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\DiscoverableMetadataProvider.cpp" />
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\EntityAttributesEntityMatcher.cpp" />
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\EntityAttributesMetadataFilter.cpp" />
@@ -298,6 +299,7 @@
<ClInclude Include="..\..\..\saml\exceptions.h" />
<ClInclude Include="..\..\..\saml\internal.h" />
<ClInclude Include="..\..\..\saml\RootObject.h" />
+ <ClInclude Include="..\..\..\saml\saml2\metadata\AbstractDynamicMetadataProvider.h" />
<ClInclude Include="..\..\..\saml\saml2\metadata\DiscoverableMetadataProvider.h" />
<ClInclude Include="..\..\..\saml\saml2\metadata\EntityMatcher.h" />
<ClInclude Include="..\..\..\saml\SAMLConfig.h" />
diff --git a/Projects/vc15/saml/saml.vcxproj.filters b/Projects/vc15/saml/saml.vcxproj.filters
index 9edae66..a4442ef 100644
--- a/Projects/vc15/saml/saml.vcxproj.filters
+++ b/Projects/vc15/saml/saml.vcxproj.filters
@@ -378,6 +378,9 @@
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\RegistrationAuthorityEntityMatcher.cpp">
<Filter>Source Files\saml2\metadata\impl</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\saml\saml2\metadata\impl\AbstractDynamicMetadataProvider.cpp">
+ <Filter>Source Files\saml2\metadata\impl</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\saml\Assertion.h">
@@ -527,6 +530,9 @@
<ClInclude Include="..\..\..\saml\saml2\metadata\EntityMatcher.h">
<Filter>Header Files\saml2\metadata</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\saml\saml2\metadata\AbstractDynamicMetadataProvider.h">
+ <Filter>Header Files\saml2\metadata</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\saml\saml.rc">
diff --git a/saml/Makefile.am b/saml/Makefile.am
index 9c82971..f394aff 100644
--- a/saml/Makefile.am
+++ b/saml/Makefile.am
@@ -86,6 +86,7 @@ saml2mdinclude_HEADERS = \
saml2/metadata/AbstractMetadataProvider.h \
saml2/metadata/DiscoverableMetadataProvider.h \
saml2/metadata/DynamicMetadataProvider.h \
+ saml2/metadata/AbstractDynamicMetadataProvider.h \
saml2/metadata/EndpointManager.h \
saml2/metadata/EntityMatcher.h \
saml2/metadata/Metadata.h \
@@ -147,6 +148,7 @@ libsaml_la_SOURCES = \
saml2/metadata/impl/ChainingMetadataProvider.cpp \
saml2/metadata/impl/DiscoverableMetadataProvider.cpp \
saml2/metadata/impl/DynamicMetadataProvider.cpp \
+ saml2/metadata/impl/AbstractDynamicMetadataProvider.cpp \
saml2/metadata/impl/EntityAttributesEntityMatcher.cpp \
saml2/metadata/impl/EntityAttributesMetadataFilter.cpp \
saml2/metadata/impl/EntityRoleMetadataFilter.cpp \
diff --git a/saml/saml2/metadata/DynamicMetadataProvider.h b/saml/saml2/metadata/AbstractDynamicMetadataProvider.h
similarity index 84%
copy from saml/saml2/metadata/DynamicMetadataProvider.h
copy to saml/saml2/metadata/AbstractDynamicMetadataProvider.h
index 0f09bb5..be42a97 100644
--- a/saml/saml2/metadata/DynamicMetadataProvider.h
+++ b/saml/saml2/metadata/AbstractDynamicMetadataProvider.h
@@ -19,9 +19,9 @@
*/
/**
- * @file saml/saml2/metadata/DynamicMetadataProvider.h
+ * @file saml/saml2/metadata/AbstractDynamicMetadataProvider.h
*
- * Simple implementation of a dynamic caching MetadataProvider.
+ * Simple base implementation of a dynamic caching MetadataProvider.
*/
#ifndef __saml2_dynmetadataprov_h__
@@ -41,17 +41,18 @@ namespace opensaml {
/**
* Simple implementation of a dynamic, caching MetadataProvider.
*/
- class SAML_API DynamicMetadataProvider : public AbstractMetadataProvider
+ class SAML_DLLPUBLIC AbstractDynamicMetadataProvider : public AbstractMetadataProvider
{
public:
/**
* Constructor.
*
+ * @param defaultNegativeCaching - if not specified in the element, do we we cache lookup failures?
* @param e DOM to supply configuration for provider
*/
- DynamicMetadataProvider(const xercesc::DOMElement* e=nullptr);
+ AbstractDynamicMetadataProvider(const xercesc::DOMElement* e=nullptr);
- virtual ~DynamicMetadataProvider();
+ virtual ~AbstractDynamicMetadataProvider();
void init();
xmltooling::Lockable* lock();
@@ -70,7 +71,7 @@ namespace opensaml {
* @param criteria lookup criteria
* @return a valid metadata instance
*/
- virtual EntityDescriptor* resolve(const Criteria& criteria) const;
+ virtual EntityDescriptor* resolve(const Criteria& criteria) const = 0;
private:
std::string m_id;
diff --git a/saml/saml2/metadata/DynamicMetadataProvider.h b/saml/saml2/metadata/DynamicMetadataProvider.h
index 0f09bb5..d62ecd8 100644
--- a/saml/saml2/metadata/DynamicMetadataProvider.h
+++ b/saml/saml2/metadata/DynamicMetadataProvider.h
@@ -24,16 +24,10 @@
* Simple implementation of a dynamic caching MetadataProvider.
*/
-#ifndef __saml2_dynmetadataprov_h__
-#define __saml2_dynmetadataprov_h__
+#ifndef __saml2_absdynmetadataprov_h__
+#define __saml2_absdynmetadataprov_h__
-#include <saml/saml2/metadata/AbstractMetadataProvider.h>
-
-namespace xmltooling {
- class XMLTOOL_API CondWait;
- class XMLTOOL_API RWLock;
- class XMLTOOL_API Thread;
-};
+#include <saml/saml2/metadata/AbstractDynamicMetadataProvider.h>
namespace opensaml {
namespace saml2md {
@@ -41,7 +35,7 @@ namespace opensaml {
/**
* Simple implementation of a dynamic, caching MetadataProvider.
*/
- class SAML_API DynamicMetadataProvider : public AbstractMetadataProvider
+ class SAML_API DynamicMetadataProvider : public AbstractDynamicMetadataProvider
{
public:
/**
@@ -51,42 +45,9 @@ namespace opensaml {
*/
DynamicMetadataProvider(const xercesc::DOMElement* e=nullptr);
- virtual ~DynamicMetadataProvider();
-
- void init();
- xmltooling::Lockable* lock();
- void unlock();
- const char* getId() const;
- const xmltooling::XMLObject* getMetadata() const;
- std::pair<const EntityDescriptor*,const RoleDescriptor*> getEntityDescriptor(const Criteria& criteria) const;
-
protected:
- /** Controls XML schema validation. */
- bool m_validate;
-
- /**
- * Resolves a metadata instance using the supplied criteria.
- *
- * @param criteria lookup criteria
- * @return a valid metadata instance
- */
virtual EntityDescriptor* resolve(const Criteria& criteria) const;
- private:
- std::string m_id;
- std::auto_ptr<xmltooling::RWLock> m_lock;
- double m_refreshDelayFactor;
- time_t m_minCacheDuration, m_maxCacheDuration;
- typedef std::map<xmltooling::xstring,time_t> cachemap_t;
- mutable cachemap_t m_cacheMap;
-
- // Used to manage background maintenance of cache.
- bool m_shutdown;
- time_t m_cleanupInterval;
- time_t m_cleanupTimeout;
- xmltooling::CondWait* m_cleanup_wait;
- xmltooling::Thread* m_cleanup_thread;
- static void* cleanup_fn(void*);
};
};
diff --git a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractDynamicMetadataProvider.cpp
similarity index 80%
copy from saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
copy to saml/saml2/metadata/impl/AbstractDynamicMetadataProvider.cpp
index ae09b26..e2b7d7b 100644
--- a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
+++ b/saml/saml2/metadata/impl/AbstractDynamicMetadataProvider.cpp
@@ -19,22 +19,19 @@
*/
/**
- * DynamicMetadataProvider.cpp
+ * AbstractDynamicMetadataProvider.cpp
*
- * Simple implementation of a dynamic caching MetadataProvider.
+ * Simple base implementation of a dynamic caching MetadataProvider.
*/
#include "internal.h"
#include "binding/SAMLArtifact.h"
#include "saml2/metadata/Metadata.h"
-#include "saml2/metadata/DynamicMetadataProvider.h"
+#include "saml2/metadata/AbstractDynamicMetadataProvider.h"
-#include <xercesc/framework/Wrapper4InputSource.hpp>
-#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/logging.h>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
-#include <xmltooling/util/ParserPool.h>
#include <xmltooling/util/Threads.h>
#include <xmltooling/util/XMLHelper.h>
#include <xmltooling/validation/ValidatorSuite.h>
@@ -69,16 +66,7 @@ static const XMLCh minCacheDuration[] = UNICODE_LITERAL_16(m,i,n,C,a,c,h,e,D
static const XMLCh refreshDelayFactor[] = UNICODE_LITERAL_18(r,e,f,r,e,s,h,D,e,l,a,y,F,a,c,t,o,r);
static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
-namespace opensaml {
- namespace saml2md {
- MetadataProvider* SAML_DLLLOCAL DynamicMetadataProviderFactory(const DOMElement* const & e)
- {
- return new DynamicMetadataProvider(e);
- }
- };
-};
-
-DynamicMetadataProvider::DynamicMetadataProvider(const DOMElement* e)
+AbstractDynamicMetadataProvider::AbstractDynamicMetadataProvider(const DOMElement* e)
: AbstractMetadataProvider(e),
m_validate(XMLHelper::getAttrBool(e, false, validate)),
m_id(XMLHelper::getAttrString(e, "Dynamic", id)),
@@ -118,7 +106,7 @@ DynamicMetadataProvider::DynamicMetadataProvider(const DOMElement* e)
}
}
-DynamicMetadataProvider::~DynamicMetadataProvider()
+AbstractDynamicMetadataProvider::~AbstractDynamicMetadataProvider()
{
// Each entity in the map is unique (no multimap semantics), so this is safe.
clearDescriptorIndex(true);
@@ -135,9 +123,9 @@ DynamicMetadataProvider::~DynamicMetadataProvider()
}
}
-void* DynamicMetadataProvider::cleanup_fn(void* pv)
+void* AbstractDynamicMetadataProvider::cleanup_fn(void* pv)
{
- DynamicMetadataProvider* provider = reinterpret_cast<DynamicMetadataProvider*>(pv);
+ AbstractDynamicMetadataProvider* provider = reinterpret_cast<AbstractDynamicMetadataProvider*>(pv);
#ifndef WIN32
// First, let's block all signals
@@ -198,32 +186,32 @@ void* DynamicMetadataProvider::cleanup_fn(void* pv)
return nullptr;
}
-const XMLObject* DynamicMetadataProvider::getMetadata() const
+const XMLObject* AbstractDynamicMetadataProvider::getMetadata() const
{
throw MetadataException("getMetadata operation not implemented on this provider.");
}
-Lockable* DynamicMetadataProvider::lock()
+Lockable* AbstractDynamicMetadataProvider::lock()
{
m_lock->rdlock();
return this;
}
-void DynamicMetadataProvider::unlock()
+void AbstractDynamicMetadataProvider::unlock()
{
m_lock->unlock();
}
-void DynamicMetadataProvider::init()
+void AbstractDynamicMetadataProvider::init()
{
}
-const char* DynamicMetadataProvider::getId() const
+const char* AbstractDynamicMetadataProvider::getId() const
{
return m_id.c_str();
}
-pair<const EntityDescriptor*,const RoleDescriptor*> DynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
+pair<const EntityDescriptor*,const RoleDescriptor*> AbstractDynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
{
Category& log = Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic");
@@ -391,52 +379,3 @@ pair<const EntityDescriptor*,const RoleDescriptor*> DynamicMetadataProvider::get
return getEntityDescriptor(criteria);
}
-EntityDescriptor* DynamicMetadataProvider::resolve(const Criteria& criteria) const
-{
- string name;
- if (criteria.entityID_ascii) {
- name = criteria.entityID_ascii;
- }
- else if (criteria.entityID_unicode) {
- auto_ptr_char temp(criteria.entityID_unicode);
- name = temp.get();
- }
- else if (criteria.artifact) {
- throw MetadataException("Unable to resolve metadata dynamically from an artifact.");
- }
-
- try {
- DOMDocument* doc=nullptr;
- auto_ptr_XMLCh widenit(name.c_str());
- URLInputSource src(widenit.get());
- Wrapper4InputSource dsrc(&src,false);
- if (m_validate)
- doc=XMLToolingConfig::getConfig().getValidatingParser().parse(dsrc);
- else
- doc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
-
- // Wrap the document for now.
- XercesJanitor<DOMDocument> docjanitor(doc);
-
- // Unmarshall objects, binding the document.
- auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
- docjanitor.release();
-
- // Make sure it's metadata.
- EntityDescriptor* entity = dynamic_cast<EntityDescriptor*>(xmlObject.get());
- if (!entity) {
- throw MetadataException(
- "Root of metadata instance not recognized: $1", params(1,xmlObject->getElementQName().toString().c_str())
- );
- }
- xmlObject.release();
- return entity;
- }
- catch (XMLException& e) {
- auto_ptr_char msg(e.getMessage());
- Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic").error(
- "Xerces error while resolving entityID (%s): %s", name.c_str(), msg.get()
- );
- throw MetadataException(msg.get());
- }
-}
diff --git a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
index ae09b26..8d6c978 100644
--- a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
+++ b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
@@ -79,316 +79,8 @@ namespace opensaml {
};
DynamicMetadataProvider::DynamicMetadataProvider(const DOMElement* e)
- : AbstractMetadataProvider(e),
- m_validate(XMLHelper::getAttrBool(e, false, validate)),
- m_id(XMLHelper::getAttrString(e, "Dynamic", id)),
- m_lock(RWLock::create()),
- m_refreshDelayFactor(0.75),
- m_minCacheDuration(XMLHelper::getAttrInt(e, 600, minCacheDuration)),
- m_maxCacheDuration(XMLHelper::getAttrInt(e, 28800, maxCacheDuration)),
- m_shutdown(false),
- m_cleanupInterval(XMLHelper::getAttrInt(e, 1800, cleanupInterval)),
- m_cleanupTimeout(XMLHelper::getAttrInt(e, 1800, cleanupTimeout)),
- m_cleanup_wait(nullptr), m_cleanup_thread(nullptr)
+ : AbstractDynamicMetadataProvider(e)
{
- if (m_minCacheDuration > m_maxCacheDuration) {
- Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic").error(
- "minCacheDuration setting exceeds maxCacheDuration setting, lowering to match it"
- );
- m_minCacheDuration = m_maxCacheDuration;
- }
-
- const XMLCh* delay = e ? e->getAttributeNS(nullptr, refreshDelayFactor) : nullptr;
- if (delay && *delay) {
- auto_ptr_char temp(delay);
- m_refreshDelayFactor = atof(temp.get());
- if (m_refreshDelayFactor <= 0.0 || m_refreshDelayFactor >= 1.0) {
- Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic").error(
- "invalid refreshDelayFactor setting, using default"
- );
- m_refreshDelayFactor = 0.75;
- }
- }
-
- if (m_cleanupInterval > 0) {
- if (m_cleanupTimeout < 0)
- m_cleanupTimeout = 0;
- m_cleanup_wait = CondWait::create();
- m_cleanup_thread = Thread::create(&cleanup_fn, this);
- }
-}
-
-DynamicMetadataProvider::~DynamicMetadataProvider()
-{
- // Each entity in the map is unique (no multimap semantics), so this is safe.
- clearDescriptorIndex(true);
-
- if (m_cleanup_thread) {
- // Shut down the cleanup thread and let it know.
- m_shutdown = true;
- m_cleanup_wait->signal();
- m_cleanup_thread->join(nullptr);
- delete m_cleanup_thread;
- delete m_cleanup_wait;
- m_cleanup_thread = nullptr;
- m_cleanup_wait = nullptr;
- }
-}
-
-void* DynamicMetadataProvider::cleanup_fn(void* pv)
-{
- DynamicMetadataProvider* provider = reinterpret_cast<DynamicMetadataProvider*>(pv);
-
-#ifndef WIN32
- // First, let's block all signals
- Thread::mask_all_signals();
-#endif
-
- if (!provider->m_id.empty()) {
- string threadid("[");
- threadid += provider->m_id + ']';
- logging::NDC::push(threadid);
- }
-
-#ifdef _DEBUG
- xmltooling::NDC ndc("cleanup");
-#endif
-
- auto_ptr<Mutex> mutex(Mutex::create());
- mutex->lock();
-
- Category& log = Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic");
-
- log.info("cleanup thread started...running every %d seconds", provider->m_cleanupInterval);
-
- while (!provider->m_shutdown) {
- provider->m_cleanup_wait->timedwait(mutex.get(), provider->m_cleanupInterval);
- if (provider->m_shutdown)
- break;
-
- log.info("cleaning dynamic metadata cache...");
-
- // Get a write lock.
- provider->m_lock->wrlock();
- SharedLock locker(provider->m_lock, false);
-
- time_t now = time(nullptr);
- // Dual iterator loop so we can remove entries while walking the map.
- for (map<xstring, time_t>::iterator i = provider->m_cacheMap.begin(), i2 = i; i != provider->m_cacheMap.end(); i = i2) {
- ++i2;
- if (now > i->second + provider->m_cleanupTimeout) {
- if (log.isDebugEnabled()) {
- auto_ptr_char id(i->first.c_str());
- log.debug("removing cache entry for (%s)", id.get());
- }
- provider->unindex(i->first.c_str(), true);
- provider->m_cacheMap.erase(i);
- }
- }
- }
-
- log.info("cleanup thread finished");
-
- mutex->unlock();
-
- if (!provider->m_id.empty()) {
- logging::NDC::pop();
- }
-
- return nullptr;
-}
-
-const XMLObject* DynamicMetadataProvider::getMetadata() const
-{
- throw MetadataException("getMetadata operation not implemented on this provider.");
-}
-
-Lockable* DynamicMetadataProvider::lock()
-{
- m_lock->rdlock();
- return this;
-}
-
-void DynamicMetadataProvider::unlock()
-{
- m_lock->unlock();
-}
-
-void DynamicMetadataProvider::init()
-{
-}
-
-const char* DynamicMetadataProvider::getId() const
-{
- return m_id.c_str();
-}
-
-pair<const EntityDescriptor*,const RoleDescriptor*> DynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
-{
- Category& log = Category::getInstance(SAML_LOGCAT ".MetadataProvider.Dynamic");
-
- bool writeLocked = false;
-
- // First we check the underlying cache.
- pair<const EntityDescriptor*,const RoleDescriptor*> entity = AbstractMetadataProvider::getEntityDescriptor(criteria);
-
- // Check to see if we're within the caching interval for a lookup of this entity.
- // This applies *even if we didn't get a hit* because the cache map tracks failed
- // lookups also, to prevent constant reload attempts.
- cachemap_t::iterator cit;
- if (entity.first) {
- cit = m_cacheMap.find(entity.first->getEntityID());
- }
- else if (criteria.entityID_ascii) {
- auto_ptr_XMLCh widetemp(criteria.entityID_ascii);
- cit = m_cacheMap.find(widetemp.get());
- }
- else if (criteria.entityID_unicode) {
- cit = m_cacheMap.find(criteria.entityID_unicode);
- }
- else if (criteria.artifact) {
- auto_ptr_XMLCh widetemp(criteria.artifact->getSource().c_str());
- cit = m_cacheMap.find(widetemp.get());
- }
- else {
- cit = m_cacheMap.end();
- }
- if (cit != m_cacheMap.end()) {
- if (time(nullptr) <= cit->second)
- return entity;
- }
-
- string name;
- if (criteria.entityID_ascii) {
- name = criteria.entityID_ascii;
- }
- else if (criteria.entityID_unicode) {
- auto_ptr_char temp(criteria.entityID_unicode);
- name = temp.get();
- }
- else if (criteria.artifact) {
- name = criteria.artifact->getSource();
- }
- else {
- return entity;
- }
-
- if (entity.first)
- log.info("metadata for (%s) is beyond caching interval, attempting to refresh", name.c_str());
- else
- log.info("resolving metadata for (%s)", name.c_str());
-
- try {
- // Try resolving it.
- auto_ptr<EntityDescriptor> entity2(resolve(criteria));
-
- // Verify the entityID.
- if (criteria.entityID_unicode && !XMLString::equals(criteria.entityID_unicode, entity2->getEntityID())) {
- log.error("metadata instance did not match expected entityID");
- return entity;
- }
- else if (criteria.artifact) {
- auto_ptr_char temp2(entity2->getEntityID());
- const string hashed(SecurityHelper::doHash("SHA1", temp2.get(), strlen(temp2.get()), true));
- if (hashed != name) {
- log.error("metadata instance did not match expected entityID");
- return entity;
- }
- }
- else {
- auto_ptr_XMLCh temp2(name.c_str());
- if (!XMLString::equals(temp2.get(), entity2->getEntityID())) {
- log.error("metadata instance did not match expected entityID");
- return entity;
- }
- }
-
- // Preprocess the metadata (even if we schema-validated).
- try {
- SchemaValidators.validate(entity2.get());
- }
- catch (exception& ex) {
- log.error("metadata instance failed manual validation checking: %s", ex.what());
- throw MetadataException("Metadata instance failed manual validation checking.");
- }
-
- // Filter it, which may throw.
- doFilters(*entity2);
-
- time_t now = time(nullptr);
- time_t cmp = now;
- if (cmp < (std::numeric_limits<int>::max() - 60))
- cmp += 60;
- if (entity2->getValidUntil() && entity2->getValidUntilEpoch() < cmp)
- throw MetadataException("Metadata was already invalid at the time of retrieval.");
-
- log.info("caching resolved metadata for (%s)", name.c_str());
-
- // Compute the smaller of the validUntil / cacheDuration constraints.
- time_t cacheExp = (entity2->getValidUntil() ? entity2->getValidUntilEpoch() : SAMLTIME_MAX) - now;
- if (entity2->getCacheDuration())
- cacheExp = min(cacheExp, entity2->getCacheDurationEpoch());
-
- // Adjust for the delay factor.
- cacheExp *= m_refreshDelayFactor;
-
- // Bound by max and min.
- if (cacheExp > m_maxCacheDuration)
- cacheExp = m_maxCacheDuration;
- else if (cacheExp < m_minCacheDuration)
- cacheExp = m_minCacheDuration;
-
- log.info("next refresh of metadata for (%s) no sooner than %u seconds", name.c_str(), cacheExp);
-
- // Upgrade our lock so we can cache the new metadata.
- m_lock->unlock();
- m_lock->wrlock();
- writeLocked = true;
-
- // Notify observers.
- emitChangeEvent(*entity2);
-
- // Record the proper refresh time.
- m_cacheMap[entity2->getEntityID()] = now + cacheExp;
-
- // Make sure we clear out any existing copies, including stale metadata or if somebody snuck in.
- cacheExp = SAMLTIME_MAX;
- unindex(entity2->getEntityID(), true); // actually frees the old instance with this ID
- indexEntity(entity2.get(), cacheExp);
- entity2.release();
-
- m_lastUpdate = now;
- }
- catch (exception& e) {
- log.error("error while resolving entityID (%s): %s", name.c_str(), e.what());
- // This will return entries that are beyond their cache period,
- // but not beyond their validity unless that criteria option was set.
- // Bump the cache period to prevent retries, making sure we have a write lock
- if (!writeLocked) {
- m_lock->unlock();
- m_lock->wrlock();
- writeLocked = true;
- }
- if (entity.first)
- m_cacheMap[entity.first->getEntityID()] = time(nullptr) + m_minCacheDuration;
- else if (criteria.entityID_unicode)
- m_cacheMap[criteria.entityID_unicode] = time(nullptr) + m_minCacheDuration;
- else {
- auto_ptr_XMLCh widetemp(name.c_str());
- m_cacheMap[widetemp.get()] = time(nullptr) + m_minCacheDuration;
- }
- log.warn("next refresh of metadata for (%s) no sooner than %u seconds", name.c_str(), m_minCacheDuration);
- return entity;
- }
-
- // Downgrade back to a read lock.
- if (writeLocked) {
- m_lock->unlock();
- m_lock->rdlock();
- }
-
- // Rinse and repeat.
- return getEntityDescriptor(criteria);
}
EntityDescriptor* DynamicMetadataProvider::resolve(const Criteria& criteria) const
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/opensaml2.git
More information about the Pkg-shibboleth-devel
mailing list