//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.IdentityModel.Tokens
{
///
/// A default implementation of the Token replay cache that is backed by
/// a bounded cache.
///
internal class DefaultTokenReplayCache : TokenReplayCache
{
static readonly int DefaultTokenReplayCacheCapacity = 500000;
static readonly TimeSpan DefaultTokenReplayCachePurgeInterval = TimeSpan.FromMinutes(1);
BoundedCache _internalCache;
///
/// Constructs the default token replay cache.
///
public DefaultTokenReplayCache()
: this(DefaultTokenReplayCache.DefaultTokenReplayCacheCapacity, DefaultTokenReplayCache.DefaultTokenReplayCachePurgeInterval)
{ }
///
/// Constructs the default token replay cache with the specified
/// capacity and purge interval.
///
/// The capacity of the token cache
/// The time interval after which the cache must be purged
public DefaultTokenReplayCache(int capacity, TimeSpan purgeInterval)
: base()
{
_internalCache = new BoundedCache(capacity, purgeInterval, StringComparer.Ordinal);
}
///
/// Gets or Sets the current Capacity of the cache in number of SecurityTokens.
///
/// If 'value' is less than or equal to zero.
public int Capacity
{
get { return _internalCache.Capacity; }
set
{
if (value <= 0)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0002));
}
_internalCache.Capacity = value;
}
}
///
/// Removes all SecurityTokens from the Cache.
///
public void Clear()
{
_internalCache.Clear();
}
///
/// Increases the maximum number of SecurityTokens that this cache will hold.
///
/// The capacity to increase.
/// The input parameter 'size' is less than or equal to zero.
/// Updated capacity
/// If size + current capacity >= int.MaxValue then capacity will be set to int.MaxValue and the cache capacity will be unbounded.
public int IncreaseCapacity(int size)
{
if (size <= 0)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("size", size, SR.GetString(SR.ID0002));
}
return _internalCache.IncreaseCapacity(size);
}
///
/// Gets or Sets the time interval that will be used when checking for expired SecurityTokens.
///
/// If 'value' is less than or equal to TimeSpan.Zero.
public TimeSpan PurgeInterval
{
get { return _internalCache.PurgeInterval; }
set
{
if (value <= TimeSpan.Zero)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0016));
}
_internalCache.PurgeInterval = value;
}
}
///
/// Attempt to add a new entry or update an existing entry.
///
/// Key to use when adding item.
/// SecurityToken to add to cache, can be null.
/// The expiration instant of the token being added.
/// Thrown if an attempt is made to add a SecurityToken if cache is at capacity.
/// Thrown if the expiration time is infinite.
public override void AddOrUpdate(string key, SecurityToken securityToken, DateTime expirationTime)
{
if (DateTime.Equals(expirationTime, DateTime.MaxValue))
{
throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID1072));
}
_internalCache.TryRemove(key);
_internalCache.TryAdd(key, securityToken, expirationTime);
}
///
/// Attempt to find if a matching entry exists in the cache.
///
/// The key to search for.
/// true if a matching entry is ifound in the cache, false otherwise
public override bool Contains(string key)
{
return _internalCache.TryFind(key);
}
///
/// Attempt to get a SecurityToken
///
/// The key to search for.
/// The found, if any, null otherwise.
public override SecurityToken Get(string key)
{
SecurityToken token;
_internalCache.TryGet(key, out token);
return token;
}
///
/// Attempt to remove an entry from the cache
///
/// The key to the entry to remove
public override void Remove(string key)
{
_internalCache.TryRemove(key);
}
}
}