/*
* 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
/**
* DynamicMetadataProvider.cpp
- *
- * Base class for caching metadata providers.
+ *
+ * Simple implementation of a dynamic caching MetadataProvider.
*/
#include "internal.h"
+#include "binding/SAMLArtifact.h"
#include "saml2/metadata/Metadata.h"
#include "saml2/metadata/DynamicMetadataProvider.h"
using namespace xmltooling;
using namespace std;
-static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
+# ifndef min
+# define min(a,b) (((a) < (b)) ? (a) : (b))
+# endif
+
+static const XMLCh maxCacheDuration[] = UNICODE_LITERAL_16(m,a,x,C,a,c,h,e,D,u,r,a,t,i,o,n);
+static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
namespace opensaml {
namespace saml2md {
};
DynamicMetadataProvider::DynamicMetadataProvider(const DOMElement* e)
- : AbstractMetadataProvider(e), m_lock(RWLock::create())
+ : AbstractMetadataProvider(e), m_maxCacheDuration(0), m_lock(RWLock::create())
{
const XMLCh* flag=e ? e->getAttributeNS(NULL,validate) : NULL;
m_validate=(XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE));
+ flag = e ? e->getAttributeNS(NULL,maxCacheDuration) : NULL;
+ if (flag && *flag)
+ m_maxCacheDuration = XMLString::parseInt(flag);
}
DynamicMetadataProvider::~DynamicMetadataProvider()
delete m_lock;
}
-const EntityDescriptor* DynamicMetadataProvider::getEntityDescriptor(const char* name, bool strict) const
+pair<const EntityDescriptor*,const RoleDescriptor*> DynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
{
// Check cache while holding the read lock.
- const EntityDescriptor* entity = AbstractMetadataProvider::getEntityDescriptor(name, strict);
- if (entity)
+ pair<const EntityDescriptor*,const RoleDescriptor*> entity = AbstractMetadataProvider::getEntityDescriptor(criteria);
+ if (entity.first) // even if the role isn't found, we're done
+ 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;
Category& log = Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic");
- log.info("resolving metadata for (%s)", name);
+ log.info("resolving metadata for (%s)", name.c_str());
// Try resolving it.
- auto_ptr<EntityDescriptor> entity2(resolve(name));
+ auto_ptr<EntityDescriptor> entity2(resolve(name.c_str()));
// Filter it, which may throw.
doFilters(*entity2.get());
- log.info("caching resolved metadata for (%s)", name);
+ log.info("caching resolved metadata for (%s)", name.c_str());
// Translate cacheDuration into validUntil.
if (entity2->getCacheDuration())
- entity2->setValidUntil(time(NULL) + entity2->getCacheDurationEpoch());
+ entity2->setValidUntil(time(NULL) + min(m_maxCacheDuration, entity2->getCacheDurationEpoch()));
// Upgrade our lock so we can cache the new metadata.
m_lock->unlock();
m_lock->rdlock();
// Rinse and repeat.
- return getEntityDescriptor(name, strict);
+ return getEntityDescriptor(criteria);
}
EntityDescriptor* DynamicMetadataProvider::resolve(const char* entityID) const
// 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();